diff --git a/README.md b/README.md index cb3781b..cf4e978 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # Tezos tutorial applications -This repository contains completed applications from the tutorials on https://docs.tezos.com/tutorials/. +This repository contains completed applications from the tutorials on https://docs.tezos.com/tutorials/ and https://docs.etherlink.com. diff --git a/etherlink-marketpulse/LICENSE.md b/etherlink-marketpulse/LICENSE.md deleted file mode 100644 index 8e6bbaa..0000000 --- a/etherlink-marketpulse/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 NOMADIC-LABS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/etherlink-marketpulse/README.md b/etherlink-marketpulse/README.md deleted file mode 100644 index 680c865..0000000 --- a/etherlink-marketpulse/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Marketpulse tutorial application - -This guide is an Etherlink tutorial to create a real application from scratch for a betting platform. -It allows users to bet cryptocurrency on the outcome of Super Bowl Championship as a way of demonstrating how to deploy and run dApps on the Etherlink platform. - -For complete instructions, see its [Introduction](https://docs.etherlink.com/tutorials/marketpulse) on docs.etherlink.com. diff --git a/etherlink-marketpulse/app/.gitignore b/etherlink-marketpulse/app/.gitignore deleted file mode 100644 index fc5ae9f..0000000 --- a/etherlink-marketpulse/app/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? -.vercel diff --git a/etherlink-marketpulse/app/README.md b/etherlink-marketpulse/app/README.md deleted file mode 100644 index 74872fd..0000000 --- a/etherlink-marketpulse/app/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js -export default tseslint.config({ - languageOptions: { - // other options... - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - }, -}) -``` - -- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` -- Optionally add `...tseslint.configs.stylisticTypeChecked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: - -```js -// eslint.config.js -import react from 'eslint-plugin-react' - -export default tseslint.config({ - // Set the react version - settings: { react: { version: '18.3' } }, - plugins: { - // Add the react plugin - react, - }, - rules: { - // other rules... - // Enable its recommended rules - ...react.configs.recommended.rules, - ...react.configs['jsx-runtime'].rules, - }, -}) -``` diff --git a/etherlink-marketpulse/app/eslint.config.js b/etherlink-marketpulse/app/eslint.config.js deleted file mode 100644 index 5e6b472..0000000 --- a/etherlink-marketpulse/app/eslint.config.js +++ /dev/null @@ -1,23 +0,0 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' -import { defineConfig, globalIgnores } from 'eslint/config' - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - js.configs.recommended, - tseslint.configs.recommended, - reactHooks.configs.flat.recommended, - reactRefresh.configs.vite, - ], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - }, -]) diff --git a/etherlink-marketpulse/app/index.html b/etherlink-marketpulse/app/index.html deleted file mode 100644 index e4b78ea..0000000 --- a/etherlink-marketpulse/app/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + React + TS - - -
- - - diff --git a/etherlink-marketpulse/app/package.json b/etherlink-marketpulse/app/package.json deleted file mode 100644 index d9a6ebd..0000000 --- a/etherlink-marketpulse/app/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "app", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "eslint .", - "postinstall": "cp ../ignition/deployments/chain-127823/deployed_addresses.json ./src && typechain --target=ethers-v6 --out-dir=./src/typechain-types --show-stack-traces ../artifacts/contracts/Marketpulse.sol/Marketpulse.json", - "preview": "vite preview" - }, - "dependencies": { - "bignumber.js": "^9.3.1", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "thirdweb": "^5.116.1", - "viem": "^2.43.5" - }, - "devDependencies": { - "@eslint/js": "^9.39.1", - "@typechain/ethers-v6": "^0.5.1", - "@types/node": "^24.10.1", - "@types/react": "^19.2.5", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.1", - "eslint": "^9.39.1", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.4.24", - "globals": "^16.5.0", - "typechain": "^8.3.2", - "typescript": "~5.9.3", - "typescript-eslint": "^8.46.4", - "vite": "^7.2.4" - } -} diff --git a/etherlink-marketpulse/app/public/chiefs.png b/etherlink-marketpulse/app/public/chiefs.png deleted file mode 100644 index b4e7854..0000000 Binary files a/etherlink-marketpulse/app/public/chiefs.png and /dev/null differ diff --git a/etherlink-marketpulse/app/public/graph.png b/etherlink-marketpulse/app/public/graph.png deleted file mode 100644 index 085e2ea..0000000 Binary files a/etherlink-marketpulse/app/public/graph.png and /dev/null differ diff --git a/etherlink-marketpulse/app/public/lions.png b/etherlink-marketpulse/app/public/lions.png deleted file mode 100644 index 0565fff..0000000 Binary files a/etherlink-marketpulse/app/public/lions.png and /dev/null differ diff --git a/etherlink-marketpulse/app/public/vite.svg b/etherlink-marketpulse/app/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/etherlink-marketpulse/app/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/etherlink-marketpulse/app/src/App.css b/etherlink-marketpulse/app/src/App.css deleted file mode 100644 index f485ebb..0000000 --- a/etherlink-marketpulse/app/src/App.css +++ /dev/null @@ -1,83 +0,0 @@ -#root { - margin: 0 auto; - padding: 2rem; - text-align: center; - - width: 100vw; - height: calc(100vh - 4rem); -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} - -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} - -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -header { - border-bottom: 1px solid #2c3f4f; - height: 100px; -} - -footer { - border-top: 1px solid #2c3f4f; -} - -hr { - color: #2c3f4f; - height: 1px; -} - -.tdTable { - align-items: center; - gap: 1rem; - width: 100%; - flex: 3 1 0%; - display: flex; - font-weight: bold; -} - -.picDiv { - height: 40px; - width: 40px; - min-width: 40px; - border-radius: 999px; - position: relative; - overflow: hidden; -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} - -h1 { - margin: unset; -} diff --git a/etherlink-marketpulse/app/src/App.tsx b/etherlink-marketpulse/app/src/App.tsx deleted file mode 100644 index bb56437..0000000 --- a/etherlink-marketpulse/app/src/App.tsx +++ /dev/null @@ -1,499 +0,0 @@ -import { Marketpulse, Marketpulse__factory } from "./typechain-types"; - -import BigNumber from "bignumber.js"; -import { useEffect, useState } from "react"; -import "./App.css"; - -import { - defineChain, - getContract, - prepareContractCall, - readContract, - sendTransaction, - ThirdwebClient, - waitForReceipt, -} from "thirdweb"; -import { ConnectButton, useActiveAccount } from "thirdweb/react"; -import { createWallet, inAppWallet } from "thirdweb/wallets"; -import { parseEther } from "viem"; -import { etherlinkShadownetTestnet } from "viem/chains"; -import { extractErrorDetails } from "./DecodeEvmTransactionLogsArgs"; -import CONTRACT_ADDRESS_JSON from "./deployed_addresses.json"; - -const wallets = [ - inAppWallet({ - auth: { - options: ["google", "email", "passkey", "phone"], - }, - }), - createWallet("io.metamask"), - createWallet("com.coinbase.wallet"), - createWallet("io.rabby"), - createWallet("com.trustwallet.app"), - createWallet("global.safe"), -]; - -//copy pasta from Solidity code as Abi and Typechain does not export enum types -enum BET_RESULT { - WIN = 0, - DRAW = 1, - PENDING = 2, -} - -interface AppProps { - thirdwebClient: ThirdwebClient; -} - -export default function App({ thirdwebClient }: AppProps) { - console.log("*************App"); - - const marketPulseContract = { - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkShadownetTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - } - - const account = useActiveAccount(); - - const [options, setOptions] = useState>(new Map()); - - const [error, setError] = useState(""); - - const [status, setStatus] = useState(BET_RESULT.PENDING); - const [winner, setWinner] = useState(undefined); - const [fees, setFees] = useState(0); - const [betKeys, setBetKeys] = useState([]); - const [_bets, setBets] = useState([]); - - const reload = async () => { - if (!account?.address) { - console.log("No address..."); - } else { - const dataStatus = await readContract({ - contract: getContract(marketPulseContract), - method: "status", - params: [], - }); - - const dataWinner = await readContract({ - contract: getContract(marketPulseContract), - method: "winner", - params: [], - }); - - const dataFEES = await readContract({ - contract: getContract(marketPulseContract), - method: "FEES", - params: [], - }); - - const dataBetKeys = await readContract({ - contract: getContract(marketPulseContract), - method: "getBetKeys", - params: [], - }); - - setStatus(dataStatus as unknown as BET_RESULT); - setWinner(dataWinner as unknown as string); - setFees(Number(dataFEES as unknown as bigint) / 100); - setBetKeys(dataBetKeys as unknown as bigint[]); - - console.log( - "**********status, winner, fees, betKeys", - status, - winner, - fees, - betKeys - ); - } - }; - - //first call to load data - useEffect(() => { - (() => reload())(); - }, [account?.address]); - - //fetch bets - - useEffect(() => { - (async () => { - if (!betKeys || betKeys.length === 0) { - console.log("no dataBetKeys"); - setBets([]); - } else { - const bets = await Promise.all( - betKeys.map( - async (betKey) => - (await readContract({ - contract: getContract(marketPulseContract), - method: "getBets", - params: [betKey], - })) as unknown as Marketpulse.BetStruct - ) - ); - setBets(bets); - - //fetch options - let newOptions = new Map(); - setOptions(newOptions); - bets.forEach((bet) => { - if (newOptions.has(bet!.option)) { - newOptions.set( - bet!.option, - newOptions.get(bet!.option)! + bet!.amount - ); //acc - } else { - newOptions.set(bet!.option, bet!.amount); - } - }); - setOptions(newOptions); - console.log("options", newOptions); - } - })(); - }, [betKeys]); - - const Ping = () => { - // Comprehensive error handling - const handlePing = async () => { - try { - const preparedContractCall = await prepareContractCall({ - contract: getContract(marketPulseContract), - method: "ping", - params: [], - }); - - console.log("preparedContractCall", preparedContractCall); - - const transaction = await sendTransaction({ - transaction: preparedContractCall, - account: account!, - }); - - //wait for tx to be included on a block - const receipt = await waitForReceipt({ - client: thirdwebClient, - chain: defineChain(etherlinkShadownetTestnet.id), - transactionHash: transaction.transactionHash, - }); - - console.log("receipt:", receipt); - - setError(""); - } catch (error) { - const errorParsed = extractErrorDetails( - error, - Marketpulse__factory.abi - ); - setError(errorParsed.message); - } - }; - - return ( - - - {!error || error === "" ? <>🟢 : <>🔴} - - ); - }; - - const BetFunction = () => { - const [amount, setAmount] = useState(BigNumber(0)); //in Ether decimals - const [option, setOption] = useState("chiefs"); - - const runFunction = async () => { - try { - const contract = getContract(marketPulseContract); - - const preparedContractCall = await prepareContractCall({ - contract, - method: "bet", - params: [option, parseEther(amount.toString(10))], - value: parseEther(amount.toString(10)), - }); - - const transaction = await sendTransaction({ - transaction: preparedContractCall, - account: account!, - }); - - //wait for tx to be included on a block - const receipt = await waitForReceipt({ - client: thirdwebClient, - chain: defineChain(etherlinkShadownetTestnet.id), - transactionHash: transaction.transactionHash, - }); - - console.log("receipt:", receipt); - - await reload(); - - setError(""); - } catch (error) { - const errorParsed = extractErrorDetails( - error, - Marketpulse__factory.abi - ); - console.log("ERROR", error); - setError(errorParsed.message); - } - }; - - const calculateOdds = (option: string, amount?: bigint): BigNumber => { - //check option exists - if (!options.has(option)) return new BigNumber(0); - - console.log( - "actuel", - options && options.size > 0 - ? new BigNumber(options.get(option)!.toString()).toString() - : 0, - "total", - new BigNumber( - [...options.values()] - .reduce((acc, newValue) => acc + newValue, amount ? amount : 0n) - .toString() - ).toString() - ); - - return options && options.size > 0 - ? new BigNumber(options.get(option)!.toString(10)) - .plus( - amount ? new BigNumber(amount.toString(10)) : new BigNumber(0) - ) - .div( - new BigNumber( - [...options.values()] - .reduce( - (acc, newValue) => acc + newValue, - amount ? amount : 0n - ) - .toString(10) - ) - ) - .plus(1) - .minus(fees) - : new BigNumber(0); - }; - - return ( - - {status && status === BET_RESULT.PENDING ? ( - <> -

Choose team

- - -

Amount

- { - if (e.target.value && !isNaN(Number(e.target.value))) { - //console.log("e.target.value",e.target.value) - setAmount(new BigNumber(e.target.value)); - } - }} - /> - -
- {account?.address ? : ""} - - - - - - - - - - - - - -
Avg price (decimal) - {options && options.size > 0 - ? calculateOdds(option, parseEther(amount.toString(10))) - .toFixed(3) - .toString() - : 0} -
Potential return - XTZ{" "} - {amount - ? calculateOdds(option, parseEther(amount.toString(10))) - .multipliedBy(amount) - .toFixed(6) - .toString() - : 0}{" "} - ( - {options && options.size > 0 - ? calculateOdds(option, parseEther(amount.toString(10))) - .minus(new BigNumber(1)) - .multipliedBy(100) - .toFixed(2) - .toString() - : 0} - %) -
- - ) : ( - <> - - Outcome: {BET_RESULT[status]} - - {winner ?
{winner}
: ""} - - )} -
- ); - }; - - const resolve = async (option: string) => { - try { - const preparedContractCall = await prepareContractCall({ - contract: getContract(marketPulseContract), - method: "resolveResult", - params: [option, BET_RESULT.WIN], - }); - - console.log("preparedContractCall", preparedContractCall); - - const transaction = await sendTransaction({ - transaction: preparedContractCall, - account: account!, - }); - - //wait for tx to be included on a block - const receipt = await waitForReceipt({ - client: thirdwebClient, - chain: defineChain(etherlinkShadownetTestnet.id), - transactionHash: transaction.transactionHash, - }); - - console.log("receipt:", receipt); - - await reload(); - - setError(""); - } catch (error) { - const errorParsed = extractErrorDetails(error, Marketpulse__factory.abi); - setError(errorParsed.message); - } - }; - - return ( - <> -
- -

Market Pulse

- -
- -
-
-
- -
-
- -
- - - - - - - - - - - {options && options.size > 0 ? ( - [...options.entries()].map(([option, amount]) => ( - - - - - - - )) - ) : ( - <> - )} - -
Outcome% chanceaction
-
- -
- {option} -
- {new BigNumber(amount.toString()) - .div( - new BigNumber( - [...options.values()] - .reduce((acc, newValue) => acc + newValue, 0n) - .toString() - ) - ) - .multipliedBy(100) - .toFixed(2)} - % - - {status && status === BET_RESULT.PENDING ? ( - - ) : ( - "" - )} -
-
- -
- {} -
-
- -
-

Errors

- - - - {account?.address ? : ""} -
- - ); -} \ No newline at end of file diff --git a/etherlink-marketpulse/app/src/DecodeEvmTransactionLogsArgs.ts b/etherlink-marketpulse/app/src/DecodeEvmTransactionLogsArgs.ts deleted file mode 100644 index 8d2af41..0000000 --- a/etherlink-marketpulse/app/src/DecodeEvmTransactionLogsArgs.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - Abi, - BaseError, - ContractFunctionRevertedError, - decodeErrorResult, -} from "viem"; - -// Type-Safe Error Handling Interface -interface DetailedError { - type: "DecodedError" | "RawError" | "UnknownError"; - message: string; - details?: string; - errorData?: any; -} - -// Advanced Error Extraction Function -export function extractErrorDetails(error: unknown, abi: Abi): DetailedError { - // Type guard for BaseError - if (error instanceof BaseError) { - // Type guard for ContractFunctionRevertedError - if (error.walk() instanceof ContractFunctionRevertedError) { - try { - // Safe data extraction - const revertError = error.walk() as ContractFunctionRevertedError; - - // Extract error data safely - const errorData = (revertError as any).data; - - // Attempt to decode error - if (errorData) { - try { - // Generic error ABI for decoding - const errorAbi = abi; - - const decodedError = decodeErrorResult({ - abi: errorAbi, - data: errorData, - }); - - return { - type: "DecodedError", - message: decodedError.errorName || "Contract function reverted", - details: decodedError.args?.toString(), - errorData, - }; - } catch { - // Fallback if decoding fails - return { - type: "RawError", - message: "Could not decode error", - errorData, - }; - } - } - } catch (extractionError) { - // Fallback error extraction - return { - type: "UnknownError", - message: error.shortMessage || "Unknown contract error", - details: error.message, - }; - } - } - - // Generic BaseError handling - return { - type: "RawError", - message: error.shortMessage || "Base error occurred", - details: error.message, - }; - } - - // Fallback for non-BaseError - return { - type: "UnknownError", - message: "message" in (error as any) ? (error as any).message : String(error), - details: error instanceof Error ? error.message : undefined, - }; -} diff --git a/etherlink-marketpulse/app/src/deployed_addresses.json b/etherlink-marketpulse/app/src/deployed_addresses.json deleted file mode 100644 index a3f2807..0000000 --- a/etherlink-marketpulse/app/src/deployed_addresses.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "MarketpulseModule#Marketpulse": "0xD380bb8E70C0a509C8b904A74258fE57F012e567" -} \ No newline at end of file diff --git a/etherlink-marketpulse/app/src/index.css b/etherlink-marketpulse/app/src/index.css deleted file mode 100644 index ea85c52..0000000 --- a/etherlink-marketpulse/app/src/index.css +++ /dev/null @@ -1,111 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #1d2b39; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} - -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #2d9cdb; - cursor: pointer; - transition: border-color 0.25s; -} - -button:hover { - border-color: #646cff; -} - -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -select { - width: inherit; - font-size: 0.875rem; - color: #858d92; - border-color: #344452; - transition: color 0.2s; - text-align: center; - border-width: 1px; - border-style: solid; - align-self: center; - padding: 1rem 1rem; - background: #1d2b39; - outline: none; - outline-color: currentcolor; - outline-style: none; - outline-width: medium; - border-radius: 8px; -} - -input { - width: calc(100% - 35px); - font-size: 0.875rem; - color: #858d92; - border-color: #344452; - transition: color 0.2s; - text-align: center; - border-width: 1px; - border-style: solid; - align-self: center; - padding: 1rem 1rem; - background: #1d2b39; - outline: none; - outline-color: currentcolor; - outline-style: none; - outline-width: medium; - border-radius: 8px; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - - a:hover { - color: #747bff; - } - - button { - background-color: #f9f9f9; - } -} diff --git a/etherlink-marketpulse/app/src/main.tsx b/etherlink-marketpulse/app/src/main.tsx deleted file mode 100644 index c5a3cbf..0000000 --- a/etherlink-marketpulse/app/src/main.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { createRoot } from "react-dom/client"; -import { createThirdwebClient } from "thirdweb"; -import { ThirdwebProvider } from "thirdweb/react"; -import App from "./App.tsx"; -import "./index.css"; - -const client = createThirdwebClient({ - clientId: "", -}); - -createRoot(document.getElementById("root")!).render( - - - -); diff --git a/etherlink-marketpulse/app/src/typechain-types/Marketpulse.ts b/etherlink-marketpulse/app/src/typechain-types/Marketpulse.ts deleted file mode 100644 index d9634d6..0000000 --- a/etherlink-marketpulse/app/src/typechain-types/Marketpulse.ts +++ /dev/null @@ -1,332 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import type { - BaseContract, - BigNumberish, - BytesLike, - FunctionFragment, - Result, - Interface, - EventFragment, - AddressLike, - ContractRunner, - ContractMethod, - Listener, -} from "ethers"; -import type { - TypedContractEvent, - TypedDeferredTopicFilter, - TypedEventLog, - TypedLogDescription, - TypedListener, - TypedContractMethod, -} from "./common"; - -export declare namespace Marketpulse { - export type BetStruct = { - id: BigNumberish; - owner: AddressLike; - option: string; - amount: BigNumberish; - }; - - export type BetStructOutput = [ - id: bigint, - owner: string, - option: string, - amount: bigint - ] & { id: bigint; owner: string; option: string; amount: bigint }; -} - -export interface MarketpulseInterface extends Interface { - getFunction( - nameOrSignature: - | "FEES" - | "ODD_DECIMALS" - | "addressToString" - | "admin" - | "bet" - | "betKeys" - | "bets" - | "calculateOdds" - | "getBetKeys" - | "getBets" - | "ping" - | "resolveResult" - | "status" - | "winner" - ): FunctionFragment; - - getEvent(nameOrSignatureOrTopic: "Pong"): EventFragment; - - encodeFunctionData(functionFragment: "FEES", values?: undefined): string; - encodeFunctionData( - functionFragment: "ODD_DECIMALS", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "addressToString", - values: [AddressLike] - ): string; - encodeFunctionData(functionFragment: "admin", values?: undefined): string; - encodeFunctionData( - functionFragment: "bet", - values: [string, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "betKeys", - values: [BigNumberish] - ): string; - encodeFunctionData(functionFragment: "bets", values: [BigNumberish]): string; - encodeFunctionData( - functionFragment: "calculateOdds", - values: [string, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "getBetKeys", - values?: undefined - ): string; - encodeFunctionData( - functionFragment: "getBets", - values: [BigNumberish] - ): string; - encodeFunctionData(functionFragment: "ping", values?: undefined): string; - encodeFunctionData( - functionFragment: "resolveResult", - values: [string, BigNumberish] - ): string; - encodeFunctionData(functionFragment: "status", values?: undefined): string; - encodeFunctionData(functionFragment: "winner", values?: undefined): string; - - decodeFunctionResult(functionFragment: "FEES", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "ODD_DECIMALS", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "addressToString", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "admin", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "bet", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "betKeys", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "bets", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "calculateOdds", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getBetKeys", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "getBets", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "ping", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "resolveResult", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "status", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "winner", data: BytesLike): Result; -} - -export namespace PongEvent { - export type InputTuple = []; - export type OutputTuple = []; - export interface OutputObject {} - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export interface Marketpulse extends BaseContract { - connect(runner?: ContractRunner | null): Marketpulse; - waitForDeployment(): Promise; - - interface: MarketpulseInterface; - - queryFilter( - event: TCEvent, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - queryFilter( - filter: TypedDeferredTopicFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - on( - event: TCEvent, - listener: TypedListener - ): Promise; - on( - filter: TypedDeferredTopicFilter, - listener: TypedListener - ): Promise; - - once( - event: TCEvent, - listener: TypedListener - ): Promise; - once( - filter: TypedDeferredTopicFilter, - listener: TypedListener - ): Promise; - - listeners( - event: TCEvent - ): Promise>>; - listeners(eventName?: string): Promise>; - removeAllListeners( - event?: TCEvent - ): Promise; - - FEES: TypedContractMethod<[], [bigint], "view">; - - ODD_DECIMALS: TypedContractMethod<[], [bigint], "view">; - - addressToString: TypedContractMethod<[_addr: AddressLike], [string], "view">; - - admin: TypedContractMethod<[], [string], "view">; - - bet: TypedContractMethod< - [selection: string, odds: BigNumberish], - [bigint], - "payable" - >; - - betKeys: TypedContractMethod<[arg0: BigNumberish], [bigint], "view">; - - bets: TypedContractMethod< - [arg0: BigNumberish], - [ - [bigint, string, string, bigint] & { - id: bigint; - owner: string; - option: string; - amount: bigint; - } - ], - "view" - >; - - calculateOdds: TypedContractMethod< - [option: string, betAmount: BigNumberish], - [bigint], - "view" - >; - - getBetKeys: TypedContractMethod<[], [bigint[]], "view">; - - getBets: TypedContractMethod< - [betId: BigNumberish], - [Marketpulse.BetStructOutput], - "view" - >; - - ping: TypedContractMethod<[], [void], "nonpayable">; - - resolveResult: TypedContractMethod< - [optionResult: string, result: BigNumberish], - [void], - "nonpayable" - >; - - status: TypedContractMethod<[], [bigint], "view">; - - winner: TypedContractMethod<[], [string], "view">; - - getFunction( - key: string | FunctionFragment - ): T; - - getFunction( - nameOrSignature: "FEES" - ): TypedContractMethod<[], [bigint], "view">; - getFunction( - nameOrSignature: "ODD_DECIMALS" - ): TypedContractMethod<[], [bigint], "view">; - getFunction( - nameOrSignature: "addressToString" - ): TypedContractMethod<[_addr: AddressLike], [string], "view">; - getFunction( - nameOrSignature: "admin" - ): TypedContractMethod<[], [string], "view">; - getFunction( - nameOrSignature: "bet" - ): TypedContractMethod< - [selection: string, odds: BigNumberish], - [bigint], - "payable" - >; - getFunction( - nameOrSignature: "betKeys" - ): TypedContractMethod<[arg0: BigNumberish], [bigint], "view">; - getFunction( - nameOrSignature: "bets" - ): TypedContractMethod< - [arg0: BigNumberish], - [ - [bigint, string, string, bigint] & { - id: bigint; - owner: string; - option: string; - amount: bigint; - } - ], - "view" - >; - getFunction( - nameOrSignature: "calculateOdds" - ): TypedContractMethod< - [option: string, betAmount: BigNumberish], - [bigint], - "view" - >; - getFunction( - nameOrSignature: "getBetKeys" - ): TypedContractMethod<[], [bigint[]], "view">; - getFunction( - nameOrSignature: "getBets" - ): TypedContractMethod< - [betId: BigNumberish], - [Marketpulse.BetStructOutput], - "view" - >; - getFunction( - nameOrSignature: "ping" - ): TypedContractMethod<[], [void], "nonpayable">; - getFunction( - nameOrSignature: "resolveResult" - ): TypedContractMethod< - [optionResult: string, result: BigNumberish], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "status" - ): TypedContractMethod<[], [bigint], "view">; - getFunction( - nameOrSignature: "winner" - ): TypedContractMethod<[], [string], "view">; - - getEvent( - key: "Pong" - ): TypedContractEvent< - PongEvent.InputTuple, - PongEvent.OutputTuple, - PongEvent.OutputObject - >; - - filters: { - "Pong()": TypedContractEvent< - PongEvent.InputTuple, - PongEvent.OutputTuple, - PongEvent.OutputObject - >; - Pong: TypedContractEvent< - PongEvent.InputTuple, - PongEvent.OutputTuple, - PongEvent.OutputObject - >; - }; -} diff --git a/etherlink-marketpulse/app/src/typechain-types/common.ts b/etherlink-marketpulse/app/src/typechain-types/common.ts deleted file mode 100644 index 56b5f21..0000000 --- a/etherlink-marketpulse/app/src/typechain-types/common.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import type { - FunctionFragment, - Typed, - EventFragment, - ContractTransaction, - ContractTransactionResponse, - DeferredTopicFilter, - EventLog, - TransactionRequest, - LogDescription, -} from "ethers"; - -export interface TypedDeferredTopicFilter<_TCEvent extends TypedContractEvent> - extends DeferredTopicFilter {} - -export interface TypedContractEvent< - InputTuple extends Array = any, - OutputTuple extends Array = any, - OutputObject = any -> { - (...args: Partial): TypedDeferredTopicFilter< - TypedContractEvent - >; - name: string; - fragment: EventFragment; - getFragment(...args: Partial): EventFragment; -} - -type __TypechainAOutputTuple = T extends TypedContractEvent< - infer _U, - infer W -> - ? W - : never; -type __TypechainOutputObject = T extends TypedContractEvent< - infer _U, - infer _W, - infer V -> - ? V - : never; - -export interface TypedEventLog - extends Omit { - args: __TypechainAOutputTuple & __TypechainOutputObject; -} - -export interface TypedLogDescription - extends Omit { - args: __TypechainAOutputTuple & __TypechainOutputObject; -} - -export type TypedListener = ( - ...listenerArg: [ - ...__TypechainAOutputTuple, - TypedEventLog, - ...undefined[] - ] -) => void; - -export type MinEthersFactory = { - deploy(...a: ARGS[]): Promise; -}; - -export type GetContractTypeFromFactory = F extends MinEthersFactory< - infer C, - any -> - ? C - : never; -export type GetARGsTypeFromFactory = F extends MinEthersFactory - ? Parameters - : never; - -export type StateMutability = "nonpayable" | "payable" | "view"; - -export type BaseOverrides = Omit; -export type NonPayableOverrides = Omit< - BaseOverrides, - "value" | "blockTag" | "enableCcipRead" ->; -export type PayableOverrides = Omit< - BaseOverrides, - "blockTag" | "enableCcipRead" ->; -export type ViewOverrides = Omit; -export type Overrides = S extends "nonpayable" - ? NonPayableOverrides - : S extends "payable" - ? PayableOverrides - : ViewOverrides; - -export type PostfixOverrides, S extends StateMutability> = - | A - | [...A, Overrides]; -export type ContractMethodArgs< - A extends Array, - S extends StateMutability -> = PostfixOverrides<{ [I in keyof A]-?: A[I] | Typed }, S>; - -export type DefaultReturnType = R extends Array ? R[0] : R; - -// export interface ContractMethod = Array, R = any, D extends R | ContractTransactionResponse = R | ContractTransactionResponse> { -export interface TypedContractMethod< - A extends Array = Array, - R = any, - S extends StateMutability = "payable" -> { - (...args: ContractMethodArgs): S extends "view" - ? Promise> - : Promise; - - name: string; - - fragment: FunctionFragment; - - getFragment(...args: ContractMethodArgs): FunctionFragment; - - populateTransaction( - ...args: ContractMethodArgs - ): Promise; - staticCall( - ...args: ContractMethodArgs - ): Promise>; - send(...args: ContractMethodArgs): Promise; - estimateGas(...args: ContractMethodArgs): Promise; - staticCallResult(...args: ContractMethodArgs): Promise; -} diff --git a/etherlink-marketpulse/app/src/typechain-types/factories/Marketpulse__factory.ts b/etherlink-marketpulse/app/src/typechain-types/factories/Marketpulse__factory.ts deleted file mode 100644 index 90c9fc0..0000000 --- a/etherlink-marketpulse/app/src/typechain-types/factories/Marketpulse__factory.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import { - Contract, - ContractFactory, - ContractTransactionResponse, - Interface, -} from "ethers"; -import type { Signer, ContractDeployTransaction, ContractRunner } from "ethers"; -import type { PayableOverrides } from "../common"; -import type { Marketpulse, MarketpulseInterface } from "../Marketpulse"; - -const _abi = [ - { - inputs: [], - stateMutability: "payable", - type: "constructor", - }, - { - anonymous: false, - inputs: [], - name: "Pong", - type: "event", - }, - { - inputs: [], - name: "FEES", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "ODD_DECIMALS", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "_addr", - type: "address", - }, - ], - name: "addressToString", - outputs: [ - { - internalType: "string", - name: "", - type: "string", - }, - ], - stateMutability: "pure", - type: "function", - }, - { - inputs: [], - name: "admin", - outputs: [ - { - internalType: "address payable", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "string", - name: "selection", - type: "string", - }, - { - internalType: "uint256", - name: "odds", - type: "uint256", - }, - ], - name: "bet", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "payable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - name: "betKeys", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - name: "bets", - outputs: [ - { - internalType: "uint256", - name: "id", - type: "uint256", - }, - { - internalType: "address payable", - name: "owner", - type: "address", - }, - { - internalType: "string", - name: "option", - type: "string", - }, - { - internalType: "uint256", - name: "amount", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "string", - name: "option", - type: "string", - }, - { - internalType: "uint256", - name: "betAmount", - type: "uint256", - }, - ], - name: "calculateOdds", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "getBetKeys", - outputs: [ - { - internalType: "uint256[]", - name: "", - type: "uint256[]", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "betId", - type: "uint256", - }, - ], - name: "getBets", - outputs: [ - { - components: [ - { - internalType: "uint256", - name: "id", - type: "uint256", - }, - { - internalType: "address payable", - name: "owner", - type: "address", - }, - { - internalType: "string", - name: "option", - type: "string", - }, - { - internalType: "uint256", - name: "amount", - type: "uint256", - }, - ], - internalType: "struct Marketpulse.Bet", - name: "bet", - type: "tuple", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "ping", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "string", - name: "optionResult", - type: "string", - }, - { - internalType: "enum Marketpulse.BET_RESULT", - name: "result", - type: "uint8", - }, - ], - name: "resolveResult", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "status", - outputs: [ - { - internalType: "enum Marketpulse.BET_RESULT", - name: "", - type: "uint8", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "winner", - outputs: [ - { - internalType: "string", - name: "", - type: "string", - }, - ], - stateMutability: "view", - type: "function", - }, -] as const; - -const _bytecode = - "0x60806040526002600360006101000a81548160ff021916908360028111156200002d576200002c62000078565b5b0217905550336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620000a7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61348b80620000b76000396000f3fe6080604052600436106100dd5760003560e01c80637a4f4e9c1161007f578063dfbf53ae11610059578063dfbf53ae146102d7578063e9c20cb914610302578063f65e650114610332578063f851a4401461035d576100dd565b80637a4f4e9c146102465780638b7b23ee1461026f578063bb0b64431461029a576100dd565b8063200d2ed2116100bb578063200d2ed21461018757806322af00fa146101b25780635c36b186146101f25780635e57966d14610209576100dd565b806308888c0a146100e25780631ccf69551461010d5780631d86be881461014a575b600080fd5b3480156100ee57600080fd5b506100f7610388565b6040516101049190611f41565b60405180910390f35b34801561011957600080fd5b50610134600480360381019061012f9190611f9c565b61038d565b604051610141919061210c565b60405180910390f35b34801561015657600080fd5b50610171600480360381019061016c9190612263565b6104b6565b60405161017e9190611f41565b60405180910390f35b34801561019357600080fd5b5061019c610adb565b6040516101a99190612336565b60405180910390f35b3480156101be57600080fd5b506101d960048036038101906101d49190611f9c565b610aee565b6040516101e994939291906123aa565b60405180910390f35b3480156101fe57600080fd5b50610207610bc6565b005b34801561021557600080fd5b50610230600480360381019061022b9190612434565b610c32565b60405161023d9190612461565b60405180910390f35b34801561025257600080fd5b5061026d600480360381019061026891906124a8565b610f09565b005b34801561027b57600080fd5b5061028461153f565b6040516102919190611f41565b60405180910390f35b3480156102a657600080fd5b506102c160048036038101906102bc9190611f9c565b611544565b6040516102ce9190611f41565b60405180910390f35b3480156102e357600080fd5b506102ec611568565b6040516102f99190612461565b60405180910390f35b61031c60048036038101906103179190612564565b6115f6565b6040516103299190611f41565b60405180910390f35b34801561033e57600080fd5b5061034761187d565b6040516103549190612673565b60405180910390f35b34801561036957600080fd5b506103726118d5565b60405161037f9190612695565b60405180910390f35b600a81565b610395611ee0565b60016000838152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282018054610423906126df565b80601f016020809104026020016040519081016040528092919081815260200182805461044f906126df565b801561049c5780601f106104715761010080835404028352916020019161049c565b820191906000526020600020905b81548152906001019060200180831161047f57829003601f168201915b505050505081526020016003820154815250509050919050565b60006104db6040518060600160405280603081526020016134046030913984846118f9565b6000805b6002805490508110156106b3576000600160006002848154811061050657610505612710565b5b90600052602060002001548152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160028201805461059a906126df565b80601f01602080910402602001604051908101604052809291908181526020018280546105c6906126df565b80156106135780601f106105e857610100808354040283529160200191610613565b820191906000526020600020905b8154815290600101906020018083116105f657829003601f168201915b5050505050815260200160038201548152505090508580519060200120816040015180519060200120146106a55760008061065b83606001518661199890919063ffffffff16565b915091508161069f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610696906127b1565b60405180910390fd5b80945050505b5080806001019150506104df565b506106f36040518060400160405280601581526020017f746f74616c4c6f736572416d6f756e74203a2025640000000000000000000000815250826119c7565b600083905060005b6002805490508110156108cf576000600160006002848154811061072257610721612710565b5b90600052602060002001548152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546107b6906126df565b80601f01602080910402602001604051908101604052809291908181526020018280546107e2906126df565b801561082f5780601f106108045761010080835404028352916020019161082f565b820191906000526020600020905b81548152906001019060200180831161081257829003601f168201915b5050505050815260200160038201548152505090508680519060200120816040015180519060200120036108c15760008061087783606001518661199890919063ffffffff16565b91509150816108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b290612843565b60405180910390fd5b80945050505b5080806001019150506106fb565b5061090f6040518060400160405280601781526020017f746f74616c57696e6e6572416d6f756e7420203a202564000000000000000000815250826119c7565b600061092883600a8061092291906129c5565b84611a63565b90506109696040518060400160405280601981526020017f7061727420706572204f44445f444543494d414c203a20256400000000000000815250826119c7565b60008061098b600a8061097c91906129c5565b8461199890919063ffffffff16565b91509150816109cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c690612a5c565b60405180910390fd5b610a0e6040518060400160405280601481526020017f6f6464776974686f75744665657320203a202564000000000000000000000000815250826119c7565b600080610a486064600a80610a2391906129c5565b600a610a2f9190612a7c565b610a399190612aed565b84611b5190919063ffffffff16565b9150915081610a8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8390612b6a565b60405180910390fd5b610acb6040518060400160405280600981526020017f6f646420203a2025640000000000000000000000000000000000000000000000815250826119c7565b8097505050505050505092915050565b600360009054906101000a900460ff1681565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002018054610b3d906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054610b69906126df565b8015610bb65780601f10610b8b57610100808354040283529160200191610bb6565b820191906000526020600020905b815481529060010190602001808311610b9957829003601f168201915b5050505050908060030154905084565b610c046040518060400160405280600481526020017f50696e6700000000000000000000000000000000000000000000000000000000815250611b79565b7f4d015fcc2a20c24d7be893b3a525eac864b5a53a5f88ef7201a600465c73314e60405160405180910390a1565b606060006040518060400160405280601081526020017f3031323334353637383961626364656600000000000000000000000000000000815250905060008360601b90506000602a67ffffffffffffffff811115610c9357610c92612138565b5b6040519080825280601f01601f191660200182016040528015610cc55781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110610cfd57610cfc612710565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110610d6157610d60612710565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b6014811015610efd57836004848360148110610db257610db1612710565b5b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c60ff1681518110610df157610df0612710565b5b602001015160f81c60f81b82600283610e0a9190612a7c565b6002610e169190612b8a565b81518110610e2757610e26612710565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535083600f60f81b848360148110610e6f57610e6e612710565b5b1a60f81b1660f81c60ff1681518110610e8b57610e8a612710565b5b602001015160f81c60f81b82600283610ea49190612a7c565b6003610eb09190612b8a565b81518110610ec157610ec0612710565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050610d93565b50809350505050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f8160008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610c32565b604051602001610f919190612c46565b60405160208183030381529060405290610fe1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd89190612461565b60405180910390fd5b50600280811115610ff557610ff46122bf565b5b600360009054906101000a900460ff166002811115611017576110166122bf565b5b14600360009054906101000a900460ff166040516020016110389190612d23565b60405160208183030381529060405290611088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107f9190612461565b60405180910390fd5b506000600281111561109d5761109c6122bf565b5b8160028111156110b0576110af6122bf565b5b14806110e05750600160028111156110cb576110ca6122bf565b5b8160028111156110de576110dd6122bf565b5b145b61111f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111690612dbb565b60405180910390fd5b60005b600280549050811015611510576000600160006002848154811061114957611148612710565b5b90600052602060002001548152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546111dd906126df565b80601f0160208091040260200160405190810160405280929190818152602001828054611209906126df565b80156112565780601f1061122b57610100808354040283529160200191611256565b820191906000526020600020905b81548152906001019060200180831161123957829003601f168201915b5050505050815260200160038201548152505090506000600281111561127f5761127e6122bf565b5b836002811115611292576112916122bf565b5b1480156112b057508380519060200120816040015180519060200120145b156113875760006112e082606001516112ce846040015160006104b6565b600a806112db91906129c5565b611a63565b90506113266040518060400160405280601481526020017f6561726e696e6773203a20256420666f72202573000000000000000000000000815250828460200151611c12565b816020015173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611370573d6000803e3d6000fd5b5084600490816113809190612f87565b5050611502565b6001600281111561139b5761139a6122bf565b5b8360028111156113ae576113ad6122bf565b5b036114bd5760006113c68260600151600a6064611a63565b90506000806113e2838560600151611b5190919063ffffffff16565b9150915081611426576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141d906130cb565b60405180910390fd5b61146a6040518060400160405280601b81526020017f67697665206261636b206d6f6e6579203a20256420666f722025730000000000815250828660200151611c12565b836020015173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156114b4573d6000803e3d6000fd5b50505050611501565b6115006040518060400160405280600f81526020017f626574206c6f737420666f7220257300000000000000000000000000000000008152508260200151611cb1565b5b5b508080600101915050611122565b5080600360006101000a81548160ff02191690836002811115611536576115356122bf565b5b02179055505050565b600a81565b6002818154811061155457600080fd5b906000526020600020016000915090505481565b60048054611575906126df565b80601f01602080910402602001604051908101604052809291908181526020018280546115a1906126df565b80156115ee5780601f106115c3576101008083540402835291602001916115ee565b820191906000526020600020905b8154815290600101906020018083116115d157829003601f168201915b505050505081565b600080341161163a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161163190613137565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff1631341115611694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168b906131c9565b60405180910390fd5b600061169e611d4d565b905060405180608001604052808281526020013373ffffffffffffffffffffffffffffffffffffffff16815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815260200134815250600160008381526020019081526020016000206000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020190816117949190612f87565b5060608201518160030155905050600281908060018154018082558091505060019003906000526020600020016000909190919091505561180a6040518060400160405280600d81526020017f42657420256420706c6163656400000000000000000000000000000000000000815250826119c7565b611872604051806060016040528060228152602001613434602291393487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505086611dc0565b809150509392505050565b606060028054806020026020016040519081016040528092919081815260200182805480156118cb57602002820191906000526020600020905b8154815260200190600101908083116118b7575b5050505050905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611993838383604051602401611911939291906131e9565b6040516020818303038152906040527f5821efa1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611e62565b505050565b60008060008385019050848110156119b75760008092509250506119c0565b60018192509250505b9250929050565b611a5f82826040516024016119dd92919061322e565b6040516020818303038152906040527fb60e72cc000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611e62565b5050565b6000808385029050600080198587098281108382030391505060008103611a9e57838281611a9457611a93612abe565b5b0492505050611b4a565b808411611abe57611abd611ab86000861460126011611e7c565b611e96565b5b600084868809905082811182039150808303925060008560000386169050808604955080840493506001818260000304019050808302841793506000600287600302189050808702600203810290508087026002038102905080870260020381029050808702600203810290508087026002038102905080870260020381029050808502955050505050505b9392505050565b60008083831115611b685760008091509150611b72565b6001838503915091505b9250929050565b611c0f81604051602401611b8d9190612461565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611e62565b50565b611cac838383604051602401611c2a9392919061326d565b6040516020818303038152906040527f1c7ec448000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611e62565b505050565b611d498282604051602401611cc79291906132ab565b6040516020818303038152906040527f319af333000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611e62565b5050565b6000611d8d6040518060400160405280601581526020017f43616c6c696e672067656e657261746542657449640000000000000000000000815250611b79565b424433604051602001611da293929190613344565b6040516020818303038152906040528051906020012060001c905090565b611e5c84848484604051602401611dda9493929190613381565b6040516020818303038152906040527fc67ea9d1000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611e62565b50505050565b611e7981611e71611ea8611ec9565b63ffffffff16565b50565b6000611e8784611ed4565b82841802821890509392505050565b634e487b71600052806020526024601cfd5b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b611f1e819050919050565b60008115159050919050565b604051806080016040528060008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160608152602001600081525090565b611f266133d4565b565b6000819050919050565b611f3b81611f28565b82525050565b6000602082019050611f566000830184611f32565b92915050565b6000604051905090565b600080fd5b600080fd5b611f7981611f28565b8114611f8457600080fd5b50565b600081359050611f9681611f70565b92915050565b600060208284031215611fb257611fb1611f66565b5b6000611fc084828501611f87565b91505092915050565b611fd281611f28565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061200382611fd8565b9050919050565b61201381611ff8565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612053578082015181840152602081019050612038565b60008484015250505050565b6000601f19601f8301169050919050565b600061207b82612019565b6120858185612024565b9350612095818560208601612035565b61209e8161205f565b840191505092915050565b60006080830160008301516120c16000860182611fc9565b5060208301516120d4602086018261200a565b50604083015184820360408601526120ec8282612070565b91505060608301516121016060860182611fc9565b508091505092915050565b6000602082019050818103600083015261212681846120a9565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6121708261205f565b810181811067ffffffffffffffff8211171561218f5761218e612138565b5b80604052505050565b60006121a2611f5c565b90506121ae8282612167565b919050565b600067ffffffffffffffff8211156121ce576121cd612138565b5b6121d78261205f565b9050602081019050919050565b82818337600083830152505050565b6000612206612201846121b3565b612198565b90508281526020810184848401111561222257612221612133565b5b61222d8482856121e4565b509392505050565b600082601f83011261224a5761224961212e565b5b813561225a8482602086016121f3565b91505092915050565b6000806040838503121561227a57612279611f66565b5b600083013567ffffffffffffffff81111561229857612297611f6b565b5b6122a485828601612235565b92505060206122b585828601611f87565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106122ff576122fe6122bf565b5b50565b6000819050612310826122ee565b919050565b600061232082612302565b9050919050565b61233081612315565b82525050565b600060208201905061234b6000830184612327565b92915050565b61235a81611ff8565b82525050565b600082825260208201905092915050565b600061237c82612019565b6123868185612360565b9350612396818560208601612035565b61239f8161205f565b840191505092915050565b60006080820190506123bf6000830187611f32565b6123cc6020830186612351565b81810360408301526123de8185612371565b90506123ed6060830184611f32565b95945050505050565b600061240182611fd8565b9050919050565b612411816123f6565b811461241c57600080fd5b50565b60008135905061242e81612408565b92915050565b60006020828403121561244a57612449611f66565b5b60006124588482850161241f565b91505092915050565b6000602082019050818103600083015261247b8184612371565b905092915050565b6003811061249057600080fd5b50565b6000813590506124a281612483565b92915050565b600080604083850312156124bf576124be611f66565b5b600083013567ffffffffffffffff8111156124dd576124dc611f6b565b5b6124e985828601612235565b92505060206124fa85828601612493565b9150509250929050565b600080fd5b600080fd5b60008083601f8401126125245761252361212e565b5b8235905067ffffffffffffffff81111561254157612540612504565b5b60208301915083600182028301111561255d5761255c612509565b5b9250929050565b60008060006040848603121561257d5761257c611f66565b5b600084013567ffffffffffffffff81111561259b5761259a611f6b565b5b6125a78682870161250e565b935093505060206125ba86828701611f87565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006125fc8383611fc9565b60208301905092915050565b6000602082019050919050565b6000612620826125c4565b61262a81856125cf565b9350612635836125e0565b8060005b8381101561266657815161264d88826125f0565b975061265883612608565b925050600181019050612639565b5085935050505092915050565b6000602082019050818103600083015261268d8184612615565b905092915050565b60006020820190506126aa6000830184612351565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806126f757607f821691505b60208210810361270a576127096126b0565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f43616e6e6f742061646420746f74616c4c6f736572416d6f756e7420616e642060008201527f6265742e616d6f756e7400000000000000000000000000000000000000000000602082015250565b600061279b602a83612360565b91506127a68261273f565b604082019050919050565b600060208201905081810360008301526127ca8161278e565b9050919050565b7f43616e6e6f742061646420746f74616c57696e6e6572416d6f756e7420616e6460008201527f206265742e616d6f756e74000000000000000000000000000000000000000000602082015250565b600061282d602b83612360565b9150612838826127d1565b604082019050919050565b6000602082019050818103600083015261285c81612820565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160011c9050919050565b6000808291508390505b60018511156128e9578086048111156128c5576128c4612863565b5b60018516156128d45780820291505b80810290506128e285612892565b94506128a9565b94509492505050565b60008261290257600190506129be565b8161291057600090506129be565b816001811461292657600281146129305761295f565b60019150506129be565b60ff84111561294257612941612863565b5b8360020a91508482111561295957612958612863565b5b506129be565b5060208310610133831016604e8410600b84101617156129945782820a90508381111561298f5761298e612863565b5b6129be565b6129a1848484600161289f565b925090508184048111156129b8576129b7612863565b5b81810290505b9392505050565b60006129d082611f28565b91506129db83611f28565b9250612a087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846128f2565b905092915050565b7f43616e6e6f7420616464207061727420616e6420310000000000000000000000600082015250565b6000612a46601583612360565b9150612a5182612a10565b602082019050919050565b60006020820190508181036000830152612a7581612a39565b9050919050565b6000612a8782611f28565b9150612a9283611f28565b9250828202612aa081611f28565b91508282048414831517612ab757612ab6612863565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612af882611f28565b9150612b0383611f28565b925082612b1357612b12612abe565b5b828204905092915050565b7f43616e6e6f742072656d6f766520666565732066726f6d206f64640000000000600082015250565b6000612b54601b83612360565b9150612b5f82612b1e565b602082019050919050565b60006020820190508181036000830152612b8381612b47565b9050919050565b6000612b9582611f28565b9150612ba083611f28565b9250828201905080821115612bb857612bb7612863565b5b92915050565b7f4f6e6c79207468652061646d696e200000000000000000000000000000000000815250565b600081905092915050565b6000612bfa82612019565b612c048185612be4565b9350612c14818560208601612035565b80840191505092915050565b7f2063616e20676976652074686520726573756c742e0000000000000000000000815250565b6000612c5182612bbe565b600f82019150612c618284612bef565b9150612c6c82612c20565b60158201915081905092915050565b7f526573756c7420697320616c726561647920676976656e20616e64206265747360008201527f20617265207265736f6c766564203a2000000000000000000000000000000000602082015250565b6000612cd7603083612be4565b9150612ce282612c7b565b603082019050919050565b60008160f81b9050919050565b6000612d0582612ced565b9050919050565b612d1d612d1882612315565b612cfa565b82525050565b6000612d2e82612cca565b9150612d3a8284612d0c565b60018201915081905092915050565b7f4f6e6c7920676976652077696e6e657273206f7220647261772c206e6f206f7460008201527f6865722063686f69636573000000000000000000000000000000000000000000602082015250565b6000612da5602b83612360565b9150612db082612d49565b604082019050919050565b60006020820190508181036000830152612dd481612d98565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612e3d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612e00565b612e478683612e00565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612e84612e7f612e7a84611f28565b612e5f565b611f28565b9050919050565b6000819050919050565b612e9e83612e69565b612eb2612eaa82612e8b565b848454612e0d565b825550505050565b600090565b612ec7612eba565b612ed2818484612e95565b505050565b5b81811015612ef657612eeb600082612ebf565b600181019050612ed8565b5050565b601f821115612f3b57612f0c81612ddb565b612f1584612df0565b81016020851015612f24578190505b612f38612f3085612df0565b830182612ed7565b50505b505050565b600082821c905092915050565b6000612f5e60001984600802612f40565b1980831691505092915050565b6000612f778383612f4d565b9150826002028217905092915050565b612f9082612019565b67ffffffffffffffff811115612fa957612fa8612138565b5b612fb382546126df565b612fbe828285612efa565b600060209050601f831160018114612ff15760008415612fdf578287015190505b612fe98582612f6b565b865550613051565b601f198416612fff86612ddb565b60005b8281101561302757848901518255600182019150602085019450602081019050613002565b868310156130445784890151613040601f891682612f4d565b8355505b6001600288020188555050505b505050505050565b7f43616e6e6f7420737562206665657320616d6f756e742066726f6d20616d6f7560008201527f6e74000000000000000000000000000000000000000000000000000000000000602082015250565b60006130b5602283612360565b91506130c082613059565b604082019050919050565b600060208201905081810360008301526130e4816130a8565b9050919050565b7f42657420616d6f756e74206d75737420626520706f7369746976652e00000000600082015250565b6000613121601c83612360565b915061312c826130eb565b602082019050919050565b6000602082019050818103600083015261315081613114565b9050919050565b7f496e73756666696369656e742062616c616e636520746f20706c61636520746860008201527f6973206265742e00000000000000000000000000000000000000000000000000602082015250565b60006131b3602783612360565b91506131be82613157565b604082019050919050565b600060208201905081810360008301526131e2816131a6565b9050919050565b600060608201905081810360008301526132038186612371565b905081810360208301526132178185612371565b90506132266040830184611f32565b949350505050565b600060408201905081810360008301526132488185612371565b90506132576020830184611f32565b9392505050565b613267816123f6565b82525050565b600060608201905081810360008301526132878186612371565b90506132966020830185611f32565b6132a3604083018461325e565b949350505050565b600060408201905081810360008301526132c58185612371565b90506132d4602083018461325e565b9392505050565b6000819050919050565b6132f66132f182611f28565b6132db565b82525050565b60008160601b9050919050565b6000613314826132fc565b9050919050565b600061332682613309565b9050919050565b61333e613339826123f6565b61331b565b82525050565b600061335082866132e5565b60208201915061336082856132e5565b602082019150613370828461332d565b601482019150819050949350505050565b6000608082019050818103600083015261339b8187612371565b90506133aa6020830186611f32565b81810360408301526133bc8185612371565b90506133cb6060830184611f32565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052605160045260246000fdfe63616c63756c6174654f64647320666f72206f7074696f6e20257320616e642062657420616d6f756e7420697320256442657420706c616365643a202564206f6e202573206174206f646473206f66202564a26469706673582212206c522febeba10230a128542012e2c972a9f8339597cd71c7a45f4c8715b5d0dd64736f6c63430008180033"; - -type MarketpulseConstructorParams = - | [signer?: Signer] - | ConstructorParameters; - -const isSuperArgs = ( - xs: MarketpulseConstructorParams -): xs is ConstructorParameters => xs.length > 1; - -export class Marketpulse__factory extends ContractFactory { - constructor(...args: MarketpulseConstructorParams) { - if (isSuperArgs(args)) { - super(...args); - } else { - super(_abi, _bytecode, args[0]); - } - } - - override getDeployTransaction( - overrides?: PayableOverrides & { from?: string } - ): Promise { - return super.getDeployTransaction(overrides || {}); - } - override deploy(overrides?: PayableOverrides & { from?: string }) { - return super.deploy(overrides || {}) as Promise< - Marketpulse & { - deploymentTransaction(): ContractTransactionResponse; - } - >; - } - override connect(runner: ContractRunner | null): Marketpulse__factory { - return super.connect(runner) as Marketpulse__factory; - } - - static readonly bytecode = _bytecode; - static readonly abi = _abi; - static createInterface(): MarketpulseInterface { - return new Interface(_abi) as MarketpulseInterface; - } - static connect(address: string, runner?: ContractRunner | null): Marketpulse { - return new Contract(address, _abi, runner) as unknown as Marketpulse; - } -} diff --git a/etherlink-marketpulse/app/src/typechain-types/factories/index.ts b/etherlink-marketpulse/app/src/typechain-types/factories/index.ts deleted file mode 100644 index fbb076a..0000000 --- a/etherlink-marketpulse/app/src/typechain-types/factories/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -export { Marketpulse__factory } from "./Marketpulse__factory"; diff --git a/etherlink-marketpulse/app/src/typechain-types/index.ts b/etherlink-marketpulse/app/src/typechain-types/index.ts deleted file mode 100644 index 298f0d1..0000000 --- a/etherlink-marketpulse/app/src/typechain-types/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -export type { Marketpulse } from "./Marketpulse"; -export * as factories from "./factories"; -export { Marketpulse__factory } from "./factories/Marketpulse__factory"; diff --git a/etherlink-marketpulse/app/src/vite-env.d.ts b/etherlink-marketpulse/app/src/vite-env.d.ts deleted file mode 100644 index 11f02fe..0000000 --- a/etherlink-marketpulse/app/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/etherlink-marketpulse/app/tsconfig.app.json b/etherlink-marketpulse/app/tsconfig.app.json deleted file mode 100644 index ba57c52..0000000 --- a/etherlink-marketpulse/app/tsconfig.app.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "target": "ES2022", - "useDefineForClassFields": true, - "lib": ["ES2022", "DOM", "DOM.Iterable"], - "module": "ESNext", - "types": ["vite/client"], - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": false, - "moduleDetection": "force", - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "erasableSyntaxOnly": false, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - }, - "include": ["src"] -} diff --git a/etherlink-marketpulse/app/tsconfig.json b/etherlink-marketpulse/app/tsconfig.json deleted file mode 100644 index 1ffef60..0000000 --- a/etherlink-marketpulse/app/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ] -} diff --git a/etherlink-marketpulse/app/tsconfig.node.json b/etherlink-marketpulse/app/tsconfig.node.json deleted file mode 100644 index 8a67f62..0000000 --- a/etherlink-marketpulse/app/tsconfig.node.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "target": "ES2023", - "lib": ["ES2023"], - "module": "ESNext", - "types": ["node"], - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "moduleDetection": "force", - "noEmit": true, - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "erasableSyntaxOnly": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/etherlink-marketpulse/app/vite.config.ts b/etherlink-marketpulse/app/vite.config.ts deleted file mode 100644 index 8b0f57b..0000000 --- a/etherlink-marketpulse/app/vite.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' - -// https://vite.dev/config/ -export default defineConfig({ - plugins: [react()], -}) diff --git a/etherlink-marketpulse/contracts/Marketpulse.sol b/etherlink-marketpulse/contracts/Marketpulse.sol deleted file mode 100644 index 95ae759..0000000 --- a/etherlink-marketpulse/contracts/Marketpulse.sol +++ /dev/null @@ -1,271 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -// Use console.log for Hardhat debugging -import "hardhat/console.sol"; - -import "@openzeppelin/contracts/utils/math/Math.sol"; - -/** - * @title Marketpulse -* @author Benjamin Fuentes -*/ -contract Marketpulse { - using Math for uint256; - - struct Bet { - uint256 id; - address payable owner; - string option; - uint256 amount; //wei - } - - enum BET_RESULT { - WIN, - DRAW, - PENDING - } - - uint256 public constant ODD_DECIMALS = 10; - uint256 public constant FEES = 10; // as PERCENTAGE unit (%) - - /** SLOTS */ - address payable public admin; - mapping(uint256 => Bet) public bets; - uint256[] public betKeys; - BET_RESULT public status = BET_RESULT.PENDING; - string public winner; - - event Pong(); - - constructor() payable { - admin = payable(msg.sender); - } - - /** - * Getter /setter - */ - function getBetKeys() public view returns (uint256[] memory) { - return betKeys; - } - - function getBets(uint256 betId) public view returns (Bet memory bet) { - return bets[betId]; - } - - /** Utility - * - * */ - - function addressToString( - address _addr - ) public pure returns (string memory) { - bytes memory alphabet = "0123456789abcdef"; - bytes20 value = bytes20(_addr); - bytes memory str = new bytes(42); - - str[0] = "0"; - str[1] = "x"; - - for (uint i = 0; i < 20; i++) { - str[2 + i * 2] = alphabet[uint(uint8(value[i] >> 4))]; - str[3 + i * 2] = alphabet[uint(uint8(value[i] & 0x0f))]; - } - - return string(str); - } - - /** - * Simple Ping - */ - function ping() public{ - console.log("Ping"); - emit Pong(); - } - - function generateBetId() private view returns (uint256) { - console.log("Calling generateBetId"); - return - uint256( - keccak256( - abi.encodePacked( - block.timestamp, - block.prevrandao, - msg.sender - ) - ) - ); - } - - /** - * place bets and returns the betId - */ - function bet( - string calldata selection, - uint256 odds - ) public payable returns (uint256) { - require(msg.value > 0, "Bet amount must be positive."); - require( - msg.value <= msg.sender.balance, - "Insufficient balance to place this bet." - ); - - uint256 betId = generateBetId(); - - bets[betId] = Bet({ - id: betId, - option: selection, - amount: msg.value, - owner: payable(msg.sender) - }); - betKeys.push(betId); - - console.log("Bet %d placed", betId); - - console.log( - "Bet placed: %d on %s at odds of %d", - msg.value, - selection, - odds - ); - return betId; - } - - /** - * - * @param option selected option - * @param betAmount (Optional: default is 0) if user want to know the output gain after putting some money on it. Otherwise it gives actual gain without betting and influencing odds calculation - * @return odds (in ODDS_DECIMAL unit) - */ - function calculateOdds( - string memory option, - uint256 betAmount //wei - ) public view returns (uint256) { - console.log( - "calculateOdds for option %s and bet amount is %d", - option, - betAmount - ); - - uint256 totalLoserAmount = 0; //wei - for (uint i = 0; i < betKeys.length; i++) { - Bet memory bet = bets[betKeys[i]]; - - if (keccak256(bytes(bet.option)) != keccak256(bytes(option))) { - (bool success, uint256 result) = totalLoserAmount.tryAdd( - bet.amount - ); - require(success, "Cannot add totalLoserAmount and bet.amount"); - totalLoserAmount = result; - } - } - console.log("totalLoserAmount: %d", totalLoserAmount); - - uint256 totalWinnerAmount = betAmount; //wei - for (uint i = 0; i < betKeys.length; i++) { - Bet memory bet = bets[betKeys[i]]; - - if (keccak256(bytes(bet.option)) == keccak256(bytes(option))) { - (bool success, uint256 result) = totalWinnerAmount.tryAdd( - bet.amount - ); - require(success, "Cannot add totalWinnerAmount and bet.amount"); - totalWinnerAmount = result; - } - } - console.log("totalWinnerAmount: %d", totalWinnerAmount); - uint256 part = Math.mulDiv( - totalLoserAmount, - 10 ** ODD_DECIMALS, - totalWinnerAmount - ); - - console.log("part per ODD_DECIMAL: %d", part); - - (bool success1, uint256 oddwithoutFees) = part.tryAdd( - 10 ** ODD_DECIMALS - ); - require(success1, "Cannot add part and 1"); - - console.log("oddwithoutFees: %d", oddwithoutFees); - - (bool success2, uint256 odd) = oddwithoutFees.trySub( - (FEES * 10 ** ODD_DECIMALS) / 100 - ); - require(success2, "Cannot remove fees from odd"); - - console.log("odd: %d", odd); - - return odd; - } - - function resolveResult( - string memory optionResult, - BET_RESULT result - ) public { - require( - msg.sender == admin, - string.concat( - "Only the admin ", - addressToString(admin), - " can give the result." - ) - ); - - require( - status == BET_RESULT.PENDING, - string( - abi.encodePacked( - "Result is already given and bets are resolved: ", - status - ) - ) - ); - - require( - result == BET_RESULT.WIN || result == BET_RESULT.DRAW, - "Only give winners or draw, no other choices" - ); - - for (uint i = 0; i < betKeys.length; i++) { - Bet memory bet = bets[betKeys[i]]; - if ( - result == BET_RESULT.WIN && - keccak256(bytes(bet.option)) == keccak256(bytes(optionResult)) - ) { - //WINNER! - uint256 earnings = Math.mulDiv( - bet.amount, - calculateOdds(bet.option, 0), - 10 ** ODD_DECIMALS - ); - console.log("earnings: %d for %s", earnings, bet.owner); - bet.owner.transfer(earnings); - winner = optionResult; - } else if (result == BET_RESULT.DRAW) { - //GIVE BACK MONEY - FEES - - uint256 feesAmount = Math.mulDiv(bet.amount, FEES, 100); - - (bool success, uint256 moneyBack) = bet.amount.trySub( - feesAmount - ); - - require(success, "Cannot sub fees amount from amount"); - - console.log( - "give back money: %d for %s", - moneyBack, - bet.owner - ); - - bet.owner.transfer(moneyBack); - } else { - //NEXT - console.log("bet lost for %s", bet.owner); - } - } - - status = result; - } -} diff --git a/etherlink-marketpulse/hardhat.config.ts b/etherlink-marketpulse/hardhat.config.ts deleted file mode 100644 index b3bf383..0000000 --- a/etherlink-marketpulse/hardhat.config.ts +++ /dev/null @@ -1,76 +0,0 @@ -import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; -import { configVariable, defineConfig } from "hardhat/config"; - -if (!configVariable("DEPLOYER_PRIVATE_KEY")) { - console.error("Missing env var DEPLOYER_PRIVATE_KEY"); -} - -const deployerPrivateKey = configVariable("DEPLOYER_PRIVATE_KEY"); - -export default defineConfig({ - plugins: [hardhatToolboxViemPlugin], - solidity: { - profiles: { - default: { - version: "0.8.28", - }, - production: { - version: "0.8.28", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - }, - }, - networks: { - hardhatMainnet: { - type: "edr-simulated", - chainType: "l1", - }, - hardhatOp: { - type: "edr-simulated", - chainType: "op", - }, - etherlinkMainnet: { - type: "http", - url: "https://node.mainnet.etherlink.com", - accounts: [deployerPrivateKey], - }, - etherlinkShadownet: { - type: "http", - url: "https://node.shadownet.etherlink.com", - accounts: [deployerPrivateKey], - }, - }, - chainDescriptors: { - 127823: { - chainType: "generic", - name: "etherlinkShadownet", - blockExplorers: { - etherscan: { - name: "EtherlinkExplorer", - apiUrl: "https://shadownet.explorer.etherlink.com/api", - url: "https://shadownet.explorer.etherlink.com", - }, - }, - }, - 42793: { - name: "EtherlinkMainnet", - } - }, - verify: { - blockscout: { - enabled: true, - }, - etherscan: { - apiKey: "DUMMY", - enabled: true, - }, - sourcify: { - enabled: false, - } - } -}); diff --git a/etherlink-marketpulse/ignition/deployments/chain-127823/artifacts/MarketpulseModule#Marketpulse.json b/etherlink-marketpulse/ignition/deployments/chain-127823/artifacts/MarketpulseModule#Marketpulse.json deleted file mode 100644 index b2f83c1..0000000 --- a/etherlink-marketpulse/ignition/deployments/chain-127823/artifacts/MarketpulseModule#Marketpulse.json +++ /dev/null @@ -1,289 +0,0 @@ -{ - "_format": "hh3-artifact-1", - "contractName": "Marketpulse", - "sourceName": "contracts/Marketpulse.sol", - "abi": [ - { - "inputs": [], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [], - "name": "Pong", - "type": "event" - }, - { - "inputs": [], - "name": "FEES", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "ODD_DECIMALS", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_addr", - "type": "address" - } - ], - "name": "addressToString", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address payable", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "selection", - "type": "string" - }, - { - "internalType": "uint256", - "name": "odds", - "type": "uint256" - } - ], - "name": "bet", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "betKeys", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "bets", - "outputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "owner", - "type": "address" - }, - { - "internalType": "string", - "name": "option", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "option", - "type": "string" - }, - { - "internalType": "uint256", - "name": "betAmount", - "type": "uint256" - } - ], - "name": "calculateOdds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getBetKeys", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "betId", - "type": "uint256" - } - ], - "name": "getBets", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "owner", - "type": "address" - }, - { - "internalType": "string", - "name": "option", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct Marketpulse.Bet", - "name": "bet", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "ping", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "optionResult", - "type": "string" - }, - { - "internalType": "enum Marketpulse.BET_RESULT", - "name": "result", - "type": "uint8" - } - ], - "name": "resolveResult", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "status", - "outputs": [ - { - "internalType": "enum Marketpulse.BET_RESULT", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "winner", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x60806040526003805460ff191660021790555f8054336001600160a01b0319909116179055611f62806100315f395ff3fe6080604052600436106100d9575f3560e01c80637a4f4e9c1161007c578063dfbf53ae11610057578063dfbf53ae14610224578063e9c20cb914610238578063f65e65011461024b578063f851a4401461026c575f5ffd5b80637a4f4e9c146101e65780638b7b23ee146100dd578063bb0b644314610205575f5ffd5b8063200d2ed2116100b7578063200d2ed21461014f57806322af00fa146101755780635c36b186146101a45780635e57966d146101ba575f5ffd5b806308888c0a146100dd5780631ccf6955146101045780631d86be8814610130575b5f5ffd5b3480156100e8575f5ffd5b506100f1600a81565b6040519081526020015b60405180910390f35b34801561010f575f5ffd5b5061012361011e36600461175f565b6102a2565b6040516100fb91906117a4565b34801561013b575f5ffd5b506100f161014a366004611890565b6103ac565b34801561015a575f5ffd5b506003546101689060ff1681565b6040516100fb91906118e6565b348015610180575f5ffd5b5061019461018f36600461175f565b610931565b6040516100fb949392919061190c565b3480156101af575f5ffd5b506101b86109ea565b005b3480156101c5575f5ffd5b506101d96101d4366004611946565b610a39565b6040516100fb919061196c565b3480156101f1575f5ffd5b506101b861020036600461197e565b610bf7565b348015610210575f5ffd5b506100f161021f36600461175f565b6110b9565b34801561022f575f5ffd5b506101d96110d8565b6100f16102463660046119d0565b611164565b348015610256575f5ffd5b5061025f61139a565b6040516100fb9190611a42565b348015610277575f5ffd5b505f5461028a906001600160a01b031681565b6040516001600160a01b0390911681526020016100fb565b6102d360405180608001604052805f81526020015f6001600160a01b03168152602001606081526020015f81525090565b5f82815260016020818152604092839020835160808101855281548152928101546001600160a01b031691830191909152600281018054929391929184019161031b90611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461034790611a84565b80156103925780601f1061036957610100808354040283529160200191610392565b820191905f5260205f20905b81548152906001019060200180831161037557829003601f168201915b505050505081526020016003820154815250509050919050565b5f6103d0604051806060016040528060308152602001611edb6030913984846113f0565b5f805b60025481101561057a575f60015f600284815481106103f4576103f4611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161044690611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461047290611a84565b80156104bd5780601f10610494576101008083540402835291602001916104bd565b820191905f5260205f20905b8154815290600101906020018083116104a057829003601f168201915b505050505081526020016003820154815250509050858051906020012081604001518051906020012014610571575f5f61050483606001518661143c90919063ffffffff16565b915091508161056d5760405162461bcd60e51b815260206004820152602a60248201527f43616e6e6f742061646420746f74616c4c6f736572416d6f756e7420616e642060448201526918995d0b985b5bdd5b9d60b21b60648201526084015b60405180910390fd5b9350505b506001016103d3565b506105b1604051806040016040528060148152602001731d1bdd185b131bdcd95c905b5bdd5b9d0e88095960621b81525082611454565b825f5b600254811015610757575f60015f600284815481106105d5576105d5611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161062790611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461065390611a84565b801561069e5780601f106106755761010080835404028352916020019161069e565b820191905f5260205f20905b81548152906001019060200180831161068157829003601f168201915b50505050508152602001600382015481525050905086805190602001208160400151805190602001200361074e575f5f6106e583606001518661143c90919063ffffffff16565b915091508161074a5760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f742061646420746f74616c57696e6e6572416d6f756e7420616e6460448201526a0818995d0b985b5bdd5b9d60aa1b6064820152608401610564565b9350505b506001016105b4565b5061078f604051806040016040528060158152602001741d1bdd185b15da5b9b995c905b5bdd5b9d0e880959605a1b81525082611454565b5f6107a58361079f600a80611bc7565b8461149d565b90506107e66040518060400160405280601881526020017f7061727420706572204f44445f444543494d414c3a202564000000000000000081525082611454565b5f806107fd6107f6600a80611bc7565b849061143c565b91509150816108465760405162461bcd60e51b815260206004820152601560248201527443616e6e6f7420616464207061727420616e64203160581b6044820152606401610564565b61087a604051806040016040528060128152602001711bd9191dda5d1a1bdd5d1199595cce88095960721b81525082611454565b5f806108a8606461088c600a80611bc7565b61089790600a611bd2565b6108a19190611bfd565b849061154d565b91509150816108f95760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742072656d6f766520666565732066726f6d206f646400000000006044820152606401610564565b610922604051806040016040528060078152602001661bd9190e88095960ca1b81525082611454565b96505050505050505b92915050565b600160208190525f91825260409091208054918101546002820180546001600160a01b03909216929161096390611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461098f90611a84565b80156109da5780601f106109b1576101008083540402835291602001916109da565b820191905f5260205f20905b8154815290600101906020018083116109bd57829003601f168201915b5050505050908060030154905084565b610a0f6040518060400160405280600481526020016350696e6760e01b81525061155d565b6040517f4d015fcc2a20c24d7be893b3a525eac864b5a53a5f88ef7201a600465c73314e905f90a1565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a808252606082810190945284841b915f91602082018180368337019050509050600360fc1b815f81518110610a9a57610a9a611abc565b60200101906001600160f81b03191690815f1a905350600f60fb1b81600181518110610ac857610ac8611abc565b60200101906001600160f81b03191690815f1a9053505f5b6014811015610bee57836004848360148110610afe57610afe611abc565b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610b2457610b24611abc565b01602001516001600160f81b03191682610b3f836002611bd2565b610b4a906002611c1c565b81518110610b5a57610b5a611abc565b60200101906001600160f81b03191690815f1a90535083838260148110610b8357610b83611abc565b825191901a600f16908110610b9a57610b9a611abc565b01602001516001600160f81b03191682610bb5836002611bd2565b610bc0906003611c1c565b81518110610bd057610bd0611abc565b60200101906001600160f81b03191690815f1a905350600101610ae0565b50949350505050565b5f546001600160a01b031633811490610c0f90610a39565b604051602001610c1f9190611c2f565b60405160208183030381529060405290610c4c5760405162461bcd60e51b8152600401610564919061196c565b50600260035460ff166002811115610c6657610c666118d2565b6003546040519290911491610c819160ff1690602001611c7d565b60405160208183030381529060405290610cae5760405162461bcd60e51b8152600401610564919061196c565b505f816002811115610cc257610cc26118d2565b1480610cdf57506001816002811115610cdd57610cdd6118d2565b145b610d3f5760405162461bcd60e51b815260206004820152602b60248201527f4f6e6c7920676976652077696e6e657273206f7220647261772c206e6f206f7460448201526a6865722063686f6963657360a81b6064820152608401610564565b5f5b600254811015611090575f60015f60028481548110610d6257610d62611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191610db490611a84565b80601f0160208091040260200160405190810160405280929190818152602001828054610de090611a84565b8015610e2b5780601f10610e0257610100808354040283529160200191610e2b565b820191905f5260205f20905b815481529060010190602001808311610e0e57829003601f168201915b50505091835250506003919091015460209091015290505f836002811115610e5557610e556118d2565b148015610e7357508380519060200120816040015180519060200120145b15610f29575f610e9f8260600151610e8f84604001515f6103ac565b610e9a600a80611bc7565b61149d565b9050610edb604051806040016040528060138152602001726561726e696e67733a20256420666f7220257360681b8152508284602001516115a3565b81602001516001600160a01b03166108fc8290811502906040515f60405180830381858888f19350505050158015610f15573d5f5f3e3d5ffd5b506004610f228682611d32565b5050611087565b6001836002811115610f3d57610f3d6118d2565b03611052575f610f548260600151600a606461149d565b90505f5f610f6f83856060015161154d90919063ffffffff16565b9150915081610fcb5760405162461bcd60e51b815260206004820152602260248201527f43616e6e6f7420737562206665657320616d6f756e742066726f6d20616d6f756044820152611b9d60f21b6064820152608401610564565b61100f6040518060400160405280601a81526020017f67697665206261636b206d6f6e65793a20256420666f722025730000000000008152508286602001516115a3565b83602001516001600160a01b03166108fc8290811502906040515f60405180830381858888f19350505050158015611049573d5f5f3e3d5ffd5b50505050611087565b6110876040518060400160405280600f81526020016e626574206c6f737420666f7220257360881b81525082602001516115ea565b50600101610d41565b506003805482919060ff191660018360028111156110b0576110b06118d2565b02179055505050565b600281815481106110c8575f80fd5b5f91825260209091200154905081565b600480546110e590611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461111190611a84565b801561115c5780601f106111335761010080835404028352916020019161115c565b820191905f5260205f20905b81548152906001019060200180831161113f57829003601f168201915b505050505081565b5f5f34116111b45760405162461bcd60e51b815260206004820152601c60248201527f42657420616d6f756e74206d75737420626520706f7369746976652e000000006044820152606401610564565b33313411156112155760405162461bcd60e51b815260206004820152602760248201527f496e73756666696369656e742062616c616e636520746f20706c61636520746860448201526634b9903132ba1760c91b6064820152608401610564565b5f61121e61162f565b90506040518060800160405280828152602001336001600160a01b0316815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920182905250938552505034602093840152508381526001808352604091829020845181559284015190830180546001600160a01b0319166001600160a01b0390921691909117905582015160028201906112c69082611d32565b5060609190910151600390910155600280546001810182555f919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0181905560408051808201909152600d81526c10995d080959081c1b1858d959609a1b60208201526113369082611454565b611390604051806060016040528060228152602001611f0b602291393487878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508992506116bb915050565b90505b9392505050565b606060028054806020026020016040519081016040528092919081815260200182805480156113e657602002820191905f5260205f20905b8154815260200190600101908083116113d2575b5050505050905090565b61143783838360405160240161140893929190611ded565b60408051601f198184030181529190526020810180516001600160e01b0316635821efa160e01b17905261170a565b505050565b80820182811015905f90825b81029150509250929050565b611499828260405160240161146a929190611e22565b60408051601f198184030181529190526020810180516001600160e01b0316632d839cb360e21b17905261170a565b5050565b5f5f5f6114aa8686611713565b91509150815f036114ce578381816114c4576114c4611be9565b0492505050611393565b8184116114e5576114e5600385150260111861172f565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b80820382811115905f9082611448565b6115a081604051602401611571919061196c565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b17905261170a565b50565b6114378383836040516024016115bb93929190611e43565b60408051601f198184030181529190526020810180516001600160e01b031663038fd88960e31b17905261170a565b6114998282604051602401611600929190611e75565b60408051601f198184030181529190526020810180516001600160e01b031663319af33360e01b17905261170a565b5f6116666040518060400160405280601581526020017410d85b1b1a5b99c819d95b995c985d1950995d1259605a1b81525061155d565b42443360405160200161169e93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b604051602081830303815290604052805190602001205f1c905090565b611704848484846040516024016116d59493929190611e9e565b60408051601f198184030181529190526020810180516001600160e01b031663c67ea9d160e01b17905261170a565b50505050565b6115a081611740565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5f6a636f6e736f6c652e6c6f6790505f5f835160208501845afa505050565b5f6020828403121561176f575f5ffd5b5035919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081528151602082015260018060a01b0360208301511660408201525f6040830151608060608401526117db60a0840182611776565b9050606084015160808401528091505092915050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112611814575f5ffd5b813567ffffffffffffffff81111561182e5761182e6117f1565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561185d5761185d6117f1565b604052818152838201602001851015611874575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f604083850312156118a1575f5ffd5b823567ffffffffffffffff8111156118b7575f5ffd5b6118c385828601611805565b95602094909401359450505050565b634e487b7160e01b5f52602160045260245ffd5b602081016003831061190657634e487b7160e01b5f52602160045260245ffd5b91905290565b8481526001600160a01b03841660208201526080604082018190525f9061193590830185611776565b905082606083015295945050505050565b5f60208284031215611956575f5ffd5b81356001600160a01b0381168114611393575f5ffd5b602081525f6113936020830184611776565b5f5f6040838503121561198f575f5ffd5b823567ffffffffffffffff8111156119a5575f5ffd5b6119b185828601611805565b9250506020830135600381106119c5575f5ffd5b809150509250929050565b5f5f5f604084860312156119e2575f5ffd5b833567ffffffffffffffff8111156119f8575f5ffd5b8401601f81018613611a08575f5ffd5b803567ffffffffffffffff811115611a1e575f5ffd5b866020828401011115611a2f575f5ffd5b6020918201979096509401359392505050565b602080825282518282018190525f918401906040840190835b81811015611a79578351835260209384019390920191600101611a5b565b509095945050505050565b600181811c90821680611a9857607f821691505b602082108103611ab657634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b6001815b6001841115611b1f57808504811115611b0357611b03611ad0565b6001841615611b1157908102905b60019390931c928002611ae8565b935093915050565b5f82611b355750600161092b565b81611b4157505f61092b565b8160018114611b575760028114611b6157611b7d565b600191505061092b565b60ff841115611b7257611b72611ad0565b50506001821b61092b565b5060208310610133831016604e8410600b8410161715611ba0575081810a61092b565b611bac5f198484611ae4565b805f1904821115611bbf57611bbf611ad0565b029392505050565b5f6113938383611b27565b808202811582820484141761092b5761092b611ad0565b634e487b7160e01b5f52601260045260245ffd5b5f82611c1757634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561092b5761092b611ad0565b6e027b7363c903a34329030b236b4b71608d1b81525f82518060208501600f85015e741031b0b71033b4bb32903a3432903932b9bab63a1760591b600f939091019283015250602401919050565b7f526573756c7420697320616c726561647920676976656e20616e64206265747381526e01030b932903932b9b7b63b32b21d1608d1b60208201525f60038310611cd557634e487b7160e01b5f52602160045260245ffd5b5060f89190911b602f82015260300190565b601f82111561143757805f5260205f20601f840160051c81016020851015611d0c5750805b601f840160051c820191505b81811015611d2b575f8155600101611d18565b5050505050565b815167ffffffffffffffff811115611d4c57611d4c6117f1565b611d6081611d5a8454611a84565b84611ce7565b6020601f821160018114611d92575f8315611d7b5750848201515b5f19600385901b1c1916600184901b178455611d2b565b5f84815260208120601f198516915b82811015611dc15787850151825560209485019460019092019101611da1565b5084821015611dde57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b606081525f611dff6060830186611776565b8281036020840152611e118186611776565b915050826040830152949350505050565b604081525f611e346040830185611776565b90508260208301529392505050565b606081525f611e556060830186611776565b6020830194909452506001600160a01b0391909116604090910152919050565b604081525f611e876040830185611776565b905060018060a01b03831660208301529392505050565b608081525f611eb06080830187611776565b8560208401528281036040840152611ec88186611776565b9150508260608301529594505050505056fe63616c63756c6174654f64647320666f72206f7074696f6e20257320616e642062657420616d6f756e7420697320256442657420706c616365643a202564206f6e202573206174206f646473206f66202564a2646970667358221220fb0f6d0e172fc4eade4bcff36b8f9da560c1f669edccdbbfddc82c5b6d7510d064736f6c634300081c0033", - "deployedBytecode": "0x6080604052600436106100d9575f3560e01c80637a4f4e9c1161007c578063dfbf53ae11610057578063dfbf53ae14610224578063e9c20cb914610238578063f65e65011461024b578063f851a4401461026c575f5ffd5b80637a4f4e9c146101e65780638b7b23ee146100dd578063bb0b644314610205575f5ffd5b8063200d2ed2116100b7578063200d2ed21461014f57806322af00fa146101755780635c36b186146101a45780635e57966d146101ba575f5ffd5b806308888c0a146100dd5780631ccf6955146101045780631d86be8814610130575b5f5ffd5b3480156100e8575f5ffd5b506100f1600a81565b6040519081526020015b60405180910390f35b34801561010f575f5ffd5b5061012361011e36600461175f565b6102a2565b6040516100fb91906117a4565b34801561013b575f5ffd5b506100f161014a366004611890565b6103ac565b34801561015a575f5ffd5b506003546101689060ff1681565b6040516100fb91906118e6565b348015610180575f5ffd5b5061019461018f36600461175f565b610931565b6040516100fb949392919061190c565b3480156101af575f5ffd5b506101b86109ea565b005b3480156101c5575f5ffd5b506101d96101d4366004611946565b610a39565b6040516100fb919061196c565b3480156101f1575f5ffd5b506101b861020036600461197e565b610bf7565b348015610210575f5ffd5b506100f161021f36600461175f565b6110b9565b34801561022f575f5ffd5b506101d96110d8565b6100f16102463660046119d0565b611164565b348015610256575f5ffd5b5061025f61139a565b6040516100fb9190611a42565b348015610277575f5ffd5b505f5461028a906001600160a01b031681565b6040516001600160a01b0390911681526020016100fb565b6102d360405180608001604052805f81526020015f6001600160a01b03168152602001606081526020015f81525090565b5f82815260016020818152604092839020835160808101855281548152928101546001600160a01b031691830191909152600281018054929391929184019161031b90611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461034790611a84565b80156103925780601f1061036957610100808354040283529160200191610392565b820191905f5260205f20905b81548152906001019060200180831161037557829003601f168201915b505050505081526020016003820154815250509050919050565b5f6103d0604051806060016040528060308152602001611edb6030913984846113f0565b5f805b60025481101561057a575f60015f600284815481106103f4576103f4611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161044690611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461047290611a84565b80156104bd5780601f10610494576101008083540402835291602001916104bd565b820191905f5260205f20905b8154815290600101906020018083116104a057829003601f168201915b505050505081526020016003820154815250509050858051906020012081604001518051906020012014610571575f5f61050483606001518661143c90919063ffffffff16565b915091508161056d5760405162461bcd60e51b815260206004820152602a60248201527f43616e6e6f742061646420746f74616c4c6f736572416d6f756e7420616e642060448201526918995d0b985b5bdd5b9d60b21b60648201526084015b60405180910390fd5b9350505b506001016103d3565b506105b1604051806040016040528060148152602001731d1bdd185b131bdcd95c905b5bdd5b9d0e88095960621b81525082611454565b825f5b600254811015610757575f60015f600284815481106105d5576105d5611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161062790611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461065390611a84565b801561069e5780601f106106755761010080835404028352916020019161069e565b820191905f5260205f20905b81548152906001019060200180831161068157829003601f168201915b50505050508152602001600382015481525050905086805190602001208160400151805190602001200361074e575f5f6106e583606001518661143c90919063ffffffff16565b915091508161074a5760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f742061646420746f74616c57696e6e6572416d6f756e7420616e6460448201526a0818995d0b985b5bdd5b9d60aa1b6064820152608401610564565b9350505b506001016105b4565b5061078f604051806040016040528060158152602001741d1bdd185b15da5b9b995c905b5bdd5b9d0e880959605a1b81525082611454565b5f6107a58361079f600a80611bc7565b8461149d565b90506107e66040518060400160405280601881526020017f7061727420706572204f44445f444543494d414c3a202564000000000000000081525082611454565b5f806107fd6107f6600a80611bc7565b849061143c565b91509150816108465760405162461bcd60e51b815260206004820152601560248201527443616e6e6f7420616464207061727420616e64203160581b6044820152606401610564565b61087a604051806040016040528060128152602001711bd9191dda5d1a1bdd5d1199595cce88095960721b81525082611454565b5f806108a8606461088c600a80611bc7565b61089790600a611bd2565b6108a19190611bfd565b849061154d565b91509150816108f95760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742072656d6f766520666565732066726f6d206f646400000000006044820152606401610564565b610922604051806040016040528060078152602001661bd9190e88095960ca1b81525082611454565b96505050505050505b92915050565b600160208190525f91825260409091208054918101546002820180546001600160a01b03909216929161096390611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461098f90611a84565b80156109da5780601f106109b1576101008083540402835291602001916109da565b820191905f5260205f20905b8154815290600101906020018083116109bd57829003601f168201915b5050505050908060030154905084565b610a0f6040518060400160405280600481526020016350696e6760e01b81525061155d565b6040517f4d015fcc2a20c24d7be893b3a525eac864b5a53a5f88ef7201a600465c73314e905f90a1565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a808252606082810190945284841b915f91602082018180368337019050509050600360fc1b815f81518110610a9a57610a9a611abc565b60200101906001600160f81b03191690815f1a905350600f60fb1b81600181518110610ac857610ac8611abc565b60200101906001600160f81b03191690815f1a9053505f5b6014811015610bee57836004848360148110610afe57610afe611abc565b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610b2457610b24611abc565b01602001516001600160f81b03191682610b3f836002611bd2565b610b4a906002611c1c565b81518110610b5a57610b5a611abc565b60200101906001600160f81b03191690815f1a90535083838260148110610b8357610b83611abc565b825191901a600f16908110610b9a57610b9a611abc565b01602001516001600160f81b03191682610bb5836002611bd2565b610bc0906003611c1c565b81518110610bd057610bd0611abc565b60200101906001600160f81b03191690815f1a905350600101610ae0565b50949350505050565b5f546001600160a01b031633811490610c0f90610a39565b604051602001610c1f9190611c2f565b60405160208183030381529060405290610c4c5760405162461bcd60e51b8152600401610564919061196c565b50600260035460ff166002811115610c6657610c666118d2565b6003546040519290911491610c819160ff1690602001611c7d565b60405160208183030381529060405290610cae5760405162461bcd60e51b8152600401610564919061196c565b505f816002811115610cc257610cc26118d2565b1480610cdf57506001816002811115610cdd57610cdd6118d2565b145b610d3f5760405162461bcd60e51b815260206004820152602b60248201527f4f6e6c7920676976652077696e6e657273206f7220647261772c206e6f206f7460448201526a6865722063686f6963657360a81b6064820152608401610564565b5f5b600254811015611090575f60015f60028481548110610d6257610d62611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191610db490611a84565b80601f0160208091040260200160405190810160405280929190818152602001828054610de090611a84565b8015610e2b5780601f10610e0257610100808354040283529160200191610e2b565b820191905f5260205f20905b815481529060010190602001808311610e0e57829003601f168201915b50505091835250506003919091015460209091015290505f836002811115610e5557610e556118d2565b148015610e7357508380519060200120816040015180519060200120145b15610f29575f610e9f8260600151610e8f84604001515f6103ac565b610e9a600a80611bc7565b61149d565b9050610edb604051806040016040528060138152602001726561726e696e67733a20256420666f7220257360681b8152508284602001516115a3565b81602001516001600160a01b03166108fc8290811502906040515f60405180830381858888f19350505050158015610f15573d5f5f3e3d5ffd5b506004610f228682611d32565b5050611087565b6001836002811115610f3d57610f3d6118d2565b03611052575f610f548260600151600a606461149d565b90505f5f610f6f83856060015161154d90919063ffffffff16565b9150915081610fcb5760405162461bcd60e51b815260206004820152602260248201527f43616e6e6f7420737562206665657320616d6f756e742066726f6d20616d6f756044820152611b9d60f21b6064820152608401610564565b61100f6040518060400160405280601a81526020017f67697665206261636b206d6f6e65793a20256420666f722025730000000000008152508286602001516115a3565b83602001516001600160a01b03166108fc8290811502906040515f60405180830381858888f19350505050158015611049573d5f5f3e3d5ffd5b50505050611087565b6110876040518060400160405280600f81526020016e626574206c6f737420666f7220257360881b81525082602001516115ea565b50600101610d41565b506003805482919060ff191660018360028111156110b0576110b06118d2565b02179055505050565b600281815481106110c8575f80fd5b5f91825260209091200154905081565b600480546110e590611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461111190611a84565b801561115c5780601f106111335761010080835404028352916020019161115c565b820191905f5260205f20905b81548152906001019060200180831161113f57829003601f168201915b505050505081565b5f5f34116111b45760405162461bcd60e51b815260206004820152601c60248201527f42657420616d6f756e74206d75737420626520706f7369746976652e000000006044820152606401610564565b33313411156112155760405162461bcd60e51b815260206004820152602760248201527f496e73756666696369656e742062616c616e636520746f20706c61636520746860448201526634b9903132ba1760c91b6064820152608401610564565b5f61121e61162f565b90506040518060800160405280828152602001336001600160a01b0316815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920182905250938552505034602093840152508381526001808352604091829020845181559284015190830180546001600160a01b0319166001600160a01b0390921691909117905582015160028201906112c69082611d32565b5060609190910151600390910155600280546001810182555f919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0181905560408051808201909152600d81526c10995d080959081c1b1858d959609a1b60208201526113369082611454565b611390604051806060016040528060228152602001611f0b602291393487878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508992506116bb915050565b90505b9392505050565b606060028054806020026020016040519081016040528092919081815260200182805480156113e657602002820191905f5260205f20905b8154815260200190600101908083116113d2575b5050505050905090565b61143783838360405160240161140893929190611ded565b60408051601f198184030181529190526020810180516001600160e01b0316635821efa160e01b17905261170a565b505050565b80820182811015905f90825b81029150509250929050565b611499828260405160240161146a929190611e22565b60408051601f198184030181529190526020810180516001600160e01b0316632d839cb360e21b17905261170a565b5050565b5f5f5f6114aa8686611713565b91509150815f036114ce578381816114c4576114c4611be9565b0492505050611393565b8184116114e5576114e5600385150260111861172f565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b80820382811115905f9082611448565b6115a081604051602401611571919061196c565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b17905261170a565b50565b6114378383836040516024016115bb93929190611e43565b60408051601f198184030181529190526020810180516001600160e01b031663038fd88960e31b17905261170a565b6114998282604051602401611600929190611e75565b60408051601f198184030181529190526020810180516001600160e01b031663319af33360e01b17905261170a565b5f6116666040518060400160405280601581526020017410d85b1b1a5b99c819d95b995c985d1950995d1259605a1b81525061155d565b42443360405160200161169e93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b604051602081830303815290604052805190602001205f1c905090565b611704848484846040516024016116d59493929190611e9e565b60408051601f198184030181529190526020810180516001600160e01b031663c67ea9d160e01b17905261170a565b50505050565b6115a081611740565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5f6a636f6e736f6c652e6c6f6790505f5f835160208501845afa505050565b5f6020828403121561176f575f5ffd5b5035919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081528151602082015260018060a01b0360208301511660408201525f6040830151608060608401526117db60a0840182611776565b9050606084015160808401528091505092915050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112611814575f5ffd5b813567ffffffffffffffff81111561182e5761182e6117f1565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561185d5761185d6117f1565b604052818152838201602001851015611874575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f604083850312156118a1575f5ffd5b823567ffffffffffffffff8111156118b7575f5ffd5b6118c385828601611805565b95602094909401359450505050565b634e487b7160e01b5f52602160045260245ffd5b602081016003831061190657634e487b7160e01b5f52602160045260245ffd5b91905290565b8481526001600160a01b03841660208201526080604082018190525f9061193590830185611776565b905082606083015295945050505050565b5f60208284031215611956575f5ffd5b81356001600160a01b0381168114611393575f5ffd5b602081525f6113936020830184611776565b5f5f6040838503121561198f575f5ffd5b823567ffffffffffffffff8111156119a5575f5ffd5b6119b185828601611805565b9250506020830135600381106119c5575f5ffd5b809150509250929050565b5f5f5f604084860312156119e2575f5ffd5b833567ffffffffffffffff8111156119f8575f5ffd5b8401601f81018613611a08575f5ffd5b803567ffffffffffffffff811115611a1e575f5ffd5b866020828401011115611a2f575f5ffd5b6020918201979096509401359392505050565b602080825282518282018190525f918401906040840190835b81811015611a79578351835260209384019390920191600101611a5b565b509095945050505050565b600181811c90821680611a9857607f821691505b602082108103611ab657634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b6001815b6001841115611b1f57808504811115611b0357611b03611ad0565b6001841615611b1157908102905b60019390931c928002611ae8565b935093915050565b5f82611b355750600161092b565b81611b4157505f61092b565b8160018114611b575760028114611b6157611b7d565b600191505061092b565b60ff841115611b7257611b72611ad0565b50506001821b61092b565b5060208310610133831016604e8410600b8410161715611ba0575081810a61092b565b611bac5f198484611ae4565b805f1904821115611bbf57611bbf611ad0565b029392505050565b5f6113938383611b27565b808202811582820484141761092b5761092b611ad0565b634e487b7160e01b5f52601260045260245ffd5b5f82611c1757634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561092b5761092b611ad0565b6e027b7363c903a34329030b236b4b71608d1b81525f82518060208501600f85015e741031b0b71033b4bb32903a3432903932b9bab63a1760591b600f939091019283015250602401919050565b7f526573756c7420697320616c726561647920676976656e20616e64206265747381526e01030b932903932b9b7b63b32b21d1608d1b60208201525f60038310611cd557634e487b7160e01b5f52602160045260245ffd5b5060f89190911b602f82015260300190565b601f82111561143757805f5260205f20601f840160051c81016020851015611d0c5750805b601f840160051c820191505b81811015611d2b575f8155600101611d18565b5050505050565b815167ffffffffffffffff811115611d4c57611d4c6117f1565b611d6081611d5a8454611a84565b84611ce7565b6020601f821160018114611d92575f8315611d7b5750848201515b5f19600385901b1c1916600184901b178455611d2b565b5f84815260208120601f198516915b82811015611dc15787850151825560209485019460019092019101611da1565b5084821015611dde57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b606081525f611dff6060830186611776565b8281036020840152611e118186611776565b915050826040830152949350505050565b604081525f611e346040830185611776565b90508260208301529392505050565b606081525f611e556060830186611776565b6020830194909452506001600160a01b0391909116604090910152919050565b604081525f611e876040830185611776565b905060018060a01b03831660208301529392505050565b608081525f611eb06080830187611776565b8560208401528281036040840152611ec88186611776565b9150508260608301529594505050505056fe63616c63756c6174654f64647320666f72206f7074696f6e20257320616e642062657420616d6f756e7420697320256442657420706c616365643a202564206f6e202573206174206f646473206f66202564a2646970667358221220fb0f6d0e172fc4eade4bcff36b8f9da560c1f669edccdbbfddc82c5b6d7510d064736f6c634300081c0033", - "linkReferences": {}, - "deployedLinkReferences": {}, - "immutableReferences": {}, - "inputSourceName": "project/contracts/Marketpulse.sol", - "buildInfoId": "solc-0_8_28-4fe1d04119025bc24d5a6233e3ab204106a72a70" -} \ No newline at end of file diff --git a/etherlink-marketpulse/ignition/deployments/chain-127823/build-info/solc-0_8_28-4fe1d04119025bc24d5a6233e3ab204106a72a70.json b/etherlink-marketpulse/ignition/deployments/chain-127823/build-info/solc-0_8_28-4fe1d04119025bc24d5a6233e3ab204106a72a70.json deleted file mode 100644 index 9a111ef..0000000 --- a/etherlink-marketpulse/ignition/deployments/chain-127823/build-info/solc-0_8_28-4fe1d04119025bc24d5a6233e3ab204106a72a70.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "_format": "hh3-sol-build-info-1", - "id": "solc-0_8_28-4fe1d04119025bc24d5a6233e3ab204106a72a70", - "solcVersion": "0.8.28", - "solcLongVersion": "0.8.28+commit.7893614a", - "userSourceNameMap": { - "contracts/Marketpulse.sol": "project/contracts/Marketpulse.sol" - }, - "input": { - "language": "Solidity", - "settings": { - "evmVersion": "cancun", - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "": [ - "ast" - ], - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata" - ] - } - }, - "remappings": [ - "project/:@openzeppelin/contracts/=npm/@openzeppelin/contracts@5.4.0/", - "project/:hardhat/=npm/hardhat@3.0.17/" - ] - }, - "sources": { - "npm/@openzeppelin/contracts@5.4.0/utils/math/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Floor, // Toward negative infinity\n Ceil, // Toward positive infinity\n Trunc, // Toward zero\n Expand // Away from zero\n }\n\n /**\n * @dev Return the 512-bit addition of two uint256.\n *\n * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n */\n function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n assembly (\"memory-safe\") {\n low := add(a, b)\n high := lt(low, a)\n }\n }\n\n /**\n * @dev Return the 512-bit multiplication of two uint256.\n *\n * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n */\n function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = high * 2²⁵⁶ + low.\n assembly (\"memory-safe\") {\n let mm := mulmod(a, b, not(0))\n low := mul(a, b)\n high := sub(sub(mm, low), lt(mm, low))\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n unchecked {\n uint256 c = a + b;\n success = c >= a;\n result = c * SafeCast.toUint(success);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n unchecked {\n uint256 c = a - b;\n success = c <= a;\n result = c * SafeCast.toUint(success);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n unchecked {\n uint256 c = a * b;\n assembly (\"memory-safe\") {\n // Only true when the multiplication doesn't overflow\n // (c / a == b) || (a == 0)\n success := or(eq(div(c, a), b), iszero(a))\n }\n // equivalent to: success ? c : 0\n result = c * SafeCast.toUint(success);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n unchecked {\n success = b > 0;\n assembly (\"memory-safe\") {\n // The `DIV` opcode returns zero when the denominator is 0.\n result := div(a, b)\n }\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n unchecked {\n success = b > 0;\n assembly (\"memory-safe\") {\n // The `MOD` opcode returns zero when the denominator is 0.\n result := mod(a, b)\n }\n }\n }\n\n /**\n * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n */\n function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n (bool success, uint256 result) = tryAdd(a, b);\n return ternary(success, result, type(uint256).max);\n }\n\n /**\n * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n */\n function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n (, uint256 result) = trySub(a, b);\n return result;\n }\n\n /**\n * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n */\n function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n (bool success, uint256 result) = tryMul(a, b);\n return ternary(success, result, type(uint256).max);\n }\n\n /**\n * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n *\n * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n * one branch when needed, making this function more expensive.\n */\n function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n unchecked {\n // branchless ternary works because:\n // b ^ (a ^ b) == a\n // b ^ 0 == b\n return b ^ ((a ^ b) * SafeCast.toUint(condition));\n }\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return ternary(a > b, a, b);\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return ternary(a < b, a, b);\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds towards infinity instead\n * of rounding towards zero.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n if (b == 0) {\n // Guarantee the same behavior as in a regular Solidity division.\n Panic.panic(Panic.DIVISION_BY_ZERO);\n }\n\n // The following calculation ensures accurate ceiling division without overflow.\n // Since a is non-zero, (a - 1) / b will not overflow.\n // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n // but the largest value we can obtain is type(uint256).max - 1, which happens\n // when a = type(uint256).max and b = 1.\n unchecked {\n return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n }\n }\n\n /**\n * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n * denominator == 0.\n *\n * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n * Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n (uint256 high, uint256 low) = mul512(x, y);\n\n // Handle non-overflow cases, 256 by 256 division.\n if (high == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return low / denominator;\n }\n\n // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n if (denominator <= high) {\n Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n }\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [high low].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n high := sub(high, gt(remainder, low))\n low := sub(low, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n uint256 twos = denominator & (0 - denominator);\n assembly (\"memory-safe\") {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [high low] by twos.\n low := div(low, twos)\n\n // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from high into low.\n low |= high * twos;\n\n // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n // works in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n inverse *= 2 - denominator * inverse; // inverse mod 2³²\n inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n // is no longer required.\n result = low * inverse;\n return result;\n }\n }\n\n /**\n * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n }\n\n /**\n * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n */\n function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n unchecked {\n (uint256 high, uint256 low) = mul512(x, y);\n if (high >= 1 << n) {\n Panic.panic(Panic.UNDER_OVERFLOW);\n }\n return (high << (256 - n)) | (low >> n);\n }\n }\n\n /**\n * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n */\n function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n }\n\n /**\n * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n *\n * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n *\n * If the input value is not inversible, 0 is returned.\n *\n * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n */\n function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n unchecked {\n if (n == 0) return 0;\n\n // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n // ax + ny = 1\n // ax = 1 + (-y)n\n // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n // If the remainder is 0 the gcd is n right away.\n uint256 remainder = a % n;\n uint256 gcd = n;\n\n // Therefore the initial coefficients are:\n // ax + ny = gcd(a, n) = n\n // 0a + 1n = n\n int256 x = 0;\n int256 y = 1;\n\n while (remainder != 0) {\n uint256 quotient = gcd / remainder;\n\n (gcd, remainder) = (\n // The old remainder is the next gcd to try.\n remainder,\n // Compute the next remainder.\n // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n // where gcd is at most n (capped to type(uint256).max)\n gcd - remainder * quotient\n );\n\n (x, y) = (\n // Increment the coefficient of a.\n y,\n // Decrement the coefficient of n.\n // Can overflow, but the result is casted to uint256 so that the\n // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n x - y * int256(quotient)\n );\n }\n\n if (gcd != 1) return 0; // No inverse exists.\n return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n }\n }\n\n /**\n * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n *\n * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n *\n * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n */\n function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n unchecked {\n return Math.modExp(a, p - 2, p);\n }\n }\n\n /**\n * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n *\n * Requirements:\n * - modulus can't be zero\n * - underlying staticcall to precompile must succeed\n *\n * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n * interpreted as 0.\n */\n function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n (bool success, uint256 result) = tryModExp(b, e, m);\n if (!success) {\n Panic.panic(Panic.DIVISION_BY_ZERO);\n }\n return result;\n }\n\n /**\n * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n * to operate modulo 0 or if the underlying precompile reverted.\n *\n * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n * of a revert, but the result may be incorrectly interpreted as 0.\n */\n function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n if (m == 0) return (false, 0);\n assembly (\"memory-safe\") {\n let ptr := mload(0x40)\n // | Offset | Content | Content (Hex) |\n // |-----------|------------|--------------------------------------------------------------------|\n // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n mstore(ptr, 0x20)\n mstore(add(ptr, 0x20), 0x20)\n mstore(add(ptr, 0x40), 0x20)\n mstore(add(ptr, 0x60), b)\n mstore(add(ptr, 0x80), e)\n mstore(add(ptr, 0xa0), m)\n\n // Given the result < m, it's guaranteed to fit in 32 bytes,\n // so we can use the memory scratch space located at offset 0.\n success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n result := mload(0x00)\n }\n }\n\n /**\n * @dev Variant of {modExp} that supports inputs of arbitrary length.\n */\n function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n (bool success, bytes memory result) = tryModExp(b, e, m);\n if (!success) {\n Panic.panic(Panic.DIVISION_BY_ZERO);\n }\n return result;\n }\n\n /**\n * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n */\n function tryModExp(\n bytes memory b,\n bytes memory e,\n bytes memory m\n ) internal view returns (bool success, bytes memory result) {\n if (_zeroBytes(m)) return (false, new bytes(0));\n\n uint256 mLen = m.length;\n\n // Encode call args in result and move the free memory pointer\n result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n assembly (\"memory-safe\") {\n let dataPtr := add(result, 0x20)\n // Write result on top of args to avoid allocating extra memory.\n success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n // Overwrite the length.\n // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n mstore(result, mLen)\n // Set the memory pointer after the returned data.\n mstore(0x40, add(dataPtr, mLen))\n }\n }\n\n /**\n * @dev Returns whether the provided byte array is zero.\n */\n function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n for (uint256 i = 0; i < byteArray.length; ++i) {\n if (byteArray[i] != 0) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n * towards zero.\n *\n * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n * using integer operations.\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n unchecked {\n // Take care of easy edge cases when a == 0 or a == 1\n if (a <= 1) {\n return a;\n }\n\n // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n // the current value as `ε_n = | x_n - sqrt(a) |`.\n //\n // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n // bigger than any uint256.\n //\n // By noticing that\n // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n // to the msb function.\n uint256 aa = a;\n uint256 xn = 1;\n\n if (aa >= (1 << 128)) {\n aa >>= 128;\n xn <<= 64;\n }\n if (aa >= (1 << 64)) {\n aa >>= 64;\n xn <<= 32;\n }\n if (aa >= (1 << 32)) {\n aa >>= 32;\n xn <<= 16;\n }\n if (aa >= (1 << 16)) {\n aa >>= 16;\n xn <<= 8;\n }\n if (aa >= (1 << 8)) {\n aa >>= 8;\n xn <<= 4;\n }\n if (aa >= (1 << 4)) {\n aa >>= 4;\n xn <<= 2;\n }\n if (aa >= (1 << 2)) {\n xn <<= 1;\n }\n\n // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n //\n // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n // This is going to be our x_0 (and ε_0)\n xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n // From here, Newton's method give us:\n // x_{n+1} = (x_n + a / x_n) / 2\n //\n // One should note that:\n // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n // = ((x_n² + a) / (2 * x_n))² - a\n // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n // = (x_n² - a)² / (2 * x_n)²\n // = ((x_n² - a) / (2 * x_n))²\n // ≥ 0\n // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n //\n // This gives us the proof of quadratic convergence of the sequence:\n // ε_{n+1} = | x_{n+1} - sqrt(a) |\n // = | (x_n + a / x_n) / 2 - sqrt(a) |\n // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n // = | (x_n - sqrt(a))² / (2 * x_n) |\n // = | ε_n² / (2 * x_n) |\n // = ε_n² / | (2 * x_n) |\n //\n // For the first iteration, we have a special case where x_0 is known:\n // ε_1 = ε_0² / | (2 * x_0) |\n // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n // ≤ 2**(2*e-4) / (3 * 2**(e-1))\n // ≤ 2**(e-3) / 3\n // ≤ 2**(e-3-log2(3))\n // ≤ 2**(e-4.5)\n //\n // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n // ε_{n+1} = ε_n² / | (2 * x_n) |\n // ≤ (2**(e-k))² / (2 * 2**(e-1))\n // ≤ 2**(2*e-2*k) / 2**e\n // ≤ 2**(e-2*k)\n xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above\n xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5\n xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9\n xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18\n xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36\n xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72\n\n // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n // sqrt(a) or sqrt(a) + 1.\n return xn - SafeCast.toUint(xn > a / xn);\n }\n }\n\n /**\n * @dev Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n }\n }\n\n /**\n * @dev Return the log in base 2 of a positive value rounded towards zero.\n * Returns 0 if given 0.\n */\n function log2(uint256 x) internal pure returns (uint256 r) {\n // If value has upper 128 bits set, log2 result is at least 128\n r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n // If upper 64 bits of 128-bit half set, add 64 to result\n r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n // If upper 32 bits of 64-bit half set, add 32 to result\n r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n // If upper 16 bits of 32-bit half set, add 16 to result\n r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n // If upper 8 bits of 16-bit half set, add 8 to result\n r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n // If upper 4 bits of 8-bit half set, add 4 to result\n r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n // Shifts value right by the current result and use it as an index into this lookup table:\n //\n // | x (4 bits) | index | table[index] = MSB position |\n // |------------|---------|-----------------------------|\n // | 0000 | 0 | table[0] = 0 |\n // | 0001 | 1 | table[1] = 0 |\n // | 0010 | 2 | table[2] = 1 |\n // | 0011 | 3 | table[3] = 1 |\n // | 0100 | 4 | table[4] = 2 |\n // | 0101 | 5 | table[5] = 2 |\n // | 0110 | 6 | table[6] = 2 |\n // | 0111 | 7 | table[7] = 2 |\n // | 1000 | 8 | table[8] = 3 |\n // | 1001 | 9 | table[9] = 3 |\n // | 1010 | 10 | table[10] = 3 |\n // | 1011 | 11 | table[11] = 3 |\n // | 1100 | 12 | table[12] = 3 |\n // | 1101 | 13 | table[13] = 3 |\n // | 1110 | 14 | table[14] = 3 |\n // | 1111 | 15 | table[15] = 3 |\n //\n // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.\n assembly (\"memory-safe\") {\n r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n }\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n }\n }\n\n /**\n * @dev Return the log in base 10 of a positive value rounded towards zero.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n }\n }\n\n /**\n * @dev Return the log in base 256 of a positive value rounded towards zero.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 x) internal pure returns (uint256 r) {\n // If value has upper 128 bits set, log2 result is at least 128\n r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n // If upper 64 bits of 128-bit half set, add 64 to result\n r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n // If upper 32 bits of 64-bit half set, add 32 to result\n r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n // If upper 16 bits of 32-bit half set, add 16 to result\n r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n }\n }\n\n /**\n * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n */\n function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n return uint8(rounding) % 2 == 1;\n }\n}\n" - }, - "npm/@openzeppelin/contracts@5.4.0/utils/math/SafeCast.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n /**\n * @dev Value doesn't fit in an uint of `bits` size.\n */\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n /**\n * @dev An int value doesn't fit in an uint of `bits` size.\n */\n error SafeCastOverflowedIntToUint(int256 value);\n\n /**\n * @dev Value doesn't fit in an int of `bits` size.\n */\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n /**\n * @dev An uint value doesn't fit in an int of `bits` size.\n */\n error SafeCastOverflowedUintToInt(uint256 value);\n\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n if (value > type(uint248).max) {\n revert SafeCastOverflowedUintDowncast(248, value);\n }\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n if (value > type(uint240).max) {\n revert SafeCastOverflowedUintDowncast(240, value);\n }\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n if (value > type(uint232).max) {\n revert SafeCastOverflowedUintDowncast(232, value);\n }\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n if (value > type(uint224).max) {\n revert SafeCastOverflowedUintDowncast(224, value);\n }\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n if (value > type(uint216).max) {\n revert SafeCastOverflowedUintDowncast(216, value);\n }\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n if (value > type(uint208).max) {\n revert SafeCastOverflowedUintDowncast(208, value);\n }\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n if (value > type(uint200).max) {\n revert SafeCastOverflowedUintDowncast(200, value);\n }\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n if (value > type(uint192).max) {\n revert SafeCastOverflowedUintDowncast(192, value);\n }\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n if (value > type(uint184).max) {\n revert SafeCastOverflowedUintDowncast(184, value);\n }\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n if (value > type(uint176).max) {\n revert SafeCastOverflowedUintDowncast(176, value);\n }\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n if (value > type(uint168).max) {\n revert SafeCastOverflowedUintDowncast(168, value);\n }\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n if (value > type(uint160).max) {\n revert SafeCastOverflowedUintDowncast(160, value);\n }\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n if (value > type(uint152).max) {\n revert SafeCastOverflowedUintDowncast(152, value);\n }\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n if (value > type(uint144).max) {\n revert SafeCastOverflowedUintDowncast(144, value);\n }\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n if (value > type(uint136).max) {\n revert SafeCastOverflowedUintDowncast(136, value);\n }\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n if (value > type(uint128).max) {\n revert SafeCastOverflowedUintDowncast(128, value);\n }\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n if (value > type(uint120).max) {\n revert SafeCastOverflowedUintDowncast(120, value);\n }\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n if (value > type(uint112).max) {\n revert SafeCastOverflowedUintDowncast(112, value);\n }\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n if (value > type(uint104).max) {\n revert SafeCastOverflowedUintDowncast(104, value);\n }\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n if (value > type(uint96).max) {\n revert SafeCastOverflowedUintDowncast(96, value);\n }\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n if (value > type(uint88).max) {\n revert SafeCastOverflowedUintDowncast(88, value);\n }\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n if (value > type(uint80).max) {\n revert SafeCastOverflowedUintDowncast(80, value);\n }\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n if (value > type(uint72).max) {\n revert SafeCastOverflowedUintDowncast(72, value);\n }\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n if (value > type(uint64).max) {\n revert SafeCastOverflowedUintDowncast(64, value);\n }\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n if (value > type(uint56).max) {\n revert SafeCastOverflowedUintDowncast(56, value);\n }\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n if (value > type(uint48).max) {\n revert SafeCastOverflowedUintDowncast(48, value);\n }\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n if (value > type(uint40).max) {\n revert SafeCastOverflowedUintDowncast(40, value);\n }\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n if (value > type(uint32).max) {\n revert SafeCastOverflowedUintDowncast(32, value);\n }\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n if (value > type(uint24).max) {\n revert SafeCastOverflowedUintDowncast(24, value);\n }\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n if (value > type(uint16).max) {\n revert SafeCastOverflowedUintDowncast(16, value);\n }\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n if (value > type(uint8).max) {\n revert SafeCastOverflowedUintDowncast(8, value);\n }\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n if (value < 0) {\n revert SafeCastOverflowedIntToUint(value);\n }\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(248, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(240, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(232, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(224, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(216, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(208, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(200, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(192, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(184, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(176, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(168, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(160, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(152, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(144, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(136, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(128, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(120, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(112, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(104, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(96, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(88, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(80, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(72, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(64, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(56, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(48, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(40, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(32, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(24, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(16, value);\n }\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n if (downcasted != value) {\n revert SafeCastOverflowedIntDowncast(8, value);\n }\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n if (value > uint256(type(int256).max)) {\n revert SafeCastOverflowedUintToInt(value);\n }\n return int256(value);\n }\n\n /**\n * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n */\n function toUint(bool b) internal pure returns (uint256 u) {\n assembly (\"memory-safe\") {\n u := iszero(iszero(b))\n }\n }\n}\n" - }, - "npm/@openzeppelin/contracts@5.4.0/utils/Panic.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n * using Panic for uint256;\n *\n * // Use any of the declared internal constants\n * function foo() { Panic.GENERIC.panic(); }\n *\n * // Alternatively\n * function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n /// @dev generic / unspecified error\n uint256 internal constant GENERIC = 0x00;\n /// @dev used by the assert() builtin\n uint256 internal constant ASSERT = 0x01;\n /// @dev arithmetic underflow or overflow\n uint256 internal constant UNDER_OVERFLOW = 0x11;\n /// @dev division or modulo by zero\n uint256 internal constant DIVISION_BY_ZERO = 0x12;\n /// @dev enum conversion error\n uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n /// @dev invalid encoding in storage\n uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n /// @dev empty array pop\n uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n /// @dev array out of bounds access\n uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n /// @dev resource error (too large allocation or too large array)\n uint256 internal constant RESOURCE_ERROR = 0x41;\n /// @dev calling invalid internal function\n uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n /// @dev Reverts with a panic code. Recommended to use with\n /// the internal constants with predefined codes.\n function panic(uint256 code) internal pure {\n assembly (\"memory-safe\") {\n mstore(0x00, 0x4e487b71)\n mstore(0x20, code)\n revert(0x1c, 0x24)\n }\n }\n}\n" - }, - "npm/hardhat@3.0.17/console.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS =\n 0x000000000000000000636F6e736F6c652e6c6f67;\n\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n pop(\n staticcall(\n gas(),\n consoleAddress,\n add(payload, 32),\n mload(payload),\n 0,\n 0\n )\n )\n }\n }\n\n function _castToPure(\n function(bytes memory) internal view fnIn\n ) internal pure returns (function(bytes memory) pure fnOut) {\n assembly {\n fnOut := fnIn\n }\n }\n\n function _sendLogPayload(bytes memory payload) internal pure {\n _castToPure(_sendLogPayloadImplementation)(payload);\n }\n\n function log() internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n function logInt(int256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n }\n\n function logBytes24(bytes24 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n }\n\n function logBytes25(bytes25 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n }\n\n function logBytes26(bytes26 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n }\n\n function logBytes27(bytes27 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n }\n\n function logBytes28(bytes28 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n }\n\n function logBytes29(bytes29 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n }\n\n function logBytes30(bytes30 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n }\n\n function logBytes31(bytes31 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n }\n\n function logBytes32(bytes32 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n }\n\n function log(uint256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function log(string memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function log(bool p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function log(address p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function log(uint256 p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256)\", p0, p1));\n }\n\n function log(uint256 p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string)\", p0, p1));\n }\n\n function log(uint256 p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool)\", p0, p1));\n }\n\n function log(uint256 p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address)\", p0, p1));\n }\n\n function log(string memory p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256)\", p0, p1));\n }\n\n function log(string memory p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n }\n\n function log(string memory p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n }\n\n function log(string memory p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n }\n\n function log(bool p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256)\", p0, p1));\n }\n\n function log(bool p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n }\n\n function log(bool p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n }\n\n function log(bool p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n }\n\n function log(address p0, uint256 p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256)\", p0, p1));\n }\n\n function log(address p0, string memory p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n }\n\n function log(address p0, bool p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n }\n\n function log(address p0, address p1) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool)\", p0, p1, p2));\n }\n\n function log(uint256 p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n }\n\n function log(string memory p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n }\n\n function log(bool p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool)\", p0, p1, p2));\n }\n\n function log(address p0, uint256 p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n }\n\n function log(address p0, string memory p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n }\n\n function log(address p0, bool p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, uint256 p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, string memory p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, bool p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n }\n\n function log(address p0, address p1, address p2) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(uint256 p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(string memory p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(bool p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, uint256 p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,uint256,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, string memory p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, bool p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, uint256 p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint256,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, string memory p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, bool p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, uint256 p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint256)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, string memory p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, bool p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n }\n\n function log(address p0, address p1, address p2, address p3) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n }\n\n}\n" - }, - "project/contracts/Marketpulse.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\n// Use console.log for Hardhat debugging\nimport \"hardhat/console.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title Marketpulse\n* @author Benjamin Fuentes\n*/\ncontract Marketpulse {\n using Math for uint256;\n\n struct Bet {\n uint256 id;\n address payable owner;\n string option;\n uint256 amount; //wei\n }\n\n enum BET_RESULT {\n WIN,\n DRAW,\n PENDING\n }\n\n uint256 public constant ODD_DECIMALS = 10;\n uint256 public constant FEES = 10; // as PERCENTAGE unit (%)\n\n /** SLOTS */\n address payable public admin;\n mapping(uint256 => Bet) public bets;\n uint256[] public betKeys;\n BET_RESULT public status = BET_RESULT.PENDING;\n string public winner;\n\n event Pong();\n\n constructor() payable {\n admin = payable(msg.sender);\n }\n\n /**\n * Getter /setter\n */\n function getBetKeys() public view returns (uint256[] memory) {\n return betKeys;\n }\n\n function getBets(uint256 betId) public view returns (Bet memory bet) {\n return bets[betId];\n }\n\n /** Utility\n *\n * */\n\n function addressToString(\n address _addr\n ) public pure returns (string memory) {\n bytes memory alphabet = \"0123456789abcdef\";\n bytes20 value = bytes20(_addr);\n bytes memory str = new bytes(42);\n\n str[0] = \"0\";\n str[1] = \"x\";\n\n for (uint i = 0; i < 20; i++) {\n str[2 + i * 2] = alphabet[uint(uint8(value[i] >> 4))];\n str[3 + i * 2] = alphabet[uint(uint8(value[i] & 0x0f))];\n }\n\n return string(str);\n }\n\n /**\n * Simple Ping\n */\n function ping() public{\n console.log(\"Ping\");\n emit Pong();\n }\n\n function generateBetId() private view returns (uint256) {\n console.log(\"Calling generateBetId\");\n return\n uint256(\n keccak256(\n abi.encodePacked(\n block.timestamp,\n block.prevrandao,\n msg.sender\n )\n )\n );\n }\n\n /**\n * place bets and returns the betId\n */\n function bet(\n string calldata selection,\n uint256 odds\n ) public payable returns (uint256) {\n require(msg.value > 0, \"Bet amount must be positive.\");\n require(\n msg.value <= msg.sender.balance,\n \"Insufficient balance to place this bet.\"\n );\n\n uint256 betId = generateBetId();\n\n bets[betId] = Bet({\n id: betId,\n option: selection,\n amount: msg.value,\n owner: payable(msg.sender)\n });\n betKeys.push(betId);\n\n console.log(\"Bet %d placed\", betId);\n\n console.log(\n \"Bet placed: %d on %s at odds of %d\",\n msg.value,\n selection,\n odds\n );\n return betId;\n }\n\n /**\n *\n * @param option selected option\n * @param betAmount (Optional: default is 0) if user want to know the output gain after putting some money on it. Otherwise it gives actual gain without betting and influencing odds calculation\n * @return odds (in ODDS_DECIMAL unit)\n */\n function calculateOdds(\n string memory option,\n uint256 betAmount //wei\n ) public view returns (uint256) {\n console.log(\n \"calculateOdds for option %s and bet amount is %d\",\n option,\n betAmount\n );\n\n uint256 totalLoserAmount = 0; //wei\n for (uint i = 0; i < betKeys.length; i++) {\n Bet memory bet = bets[betKeys[i]];\n\n if (keccak256(bytes(bet.option)) != keccak256(bytes(option))) {\n (bool success, uint256 result) = totalLoserAmount.tryAdd(\n bet.amount\n );\n require(success, \"Cannot add totalLoserAmount and bet.amount\");\n totalLoserAmount = result;\n }\n }\n console.log(\"totalLoserAmount: %d\", totalLoserAmount);\n\n uint256 totalWinnerAmount = betAmount; //wei\n for (uint i = 0; i < betKeys.length; i++) {\n Bet memory bet = bets[betKeys[i]];\n\n if (keccak256(bytes(bet.option)) == keccak256(bytes(option))) {\n (bool success, uint256 result) = totalWinnerAmount.tryAdd(\n bet.amount\n );\n require(success, \"Cannot add totalWinnerAmount and bet.amount\");\n totalWinnerAmount = result;\n }\n }\n console.log(\"totalWinnerAmount: %d\", totalWinnerAmount);\n uint256 part = Math.mulDiv(\n totalLoserAmount,\n 10 ** ODD_DECIMALS,\n totalWinnerAmount\n );\n\n console.log(\"part per ODD_DECIMAL: %d\", part);\n\n (bool success1, uint256 oddwithoutFees) = part.tryAdd(\n 10 ** ODD_DECIMALS\n );\n require(success1, \"Cannot add part and 1\");\n\n console.log(\"oddwithoutFees: %d\", oddwithoutFees);\n\n (bool success2, uint256 odd) = oddwithoutFees.trySub(\n (FEES * 10 ** ODD_DECIMALS) / 100\n );\n require(success2, \"Cannot remove fees from odd\");\n\n console.log(\"odd: %d\", odd);\n\n return odd;\n }\n\n function resolveResult(\n string memory optionResult,\n BET_RESULT result\n ) public {\n require(\n msg.sender == admin,\n string.concat(\n \"Only the admin \",\n addressToString(admin),\n \" can give the result.\"\n )\n );\n\n require(\n status == BET_RESULT.PENDING,\n string(\n abi.encodePacked(\n \"Result is already given and bets are resolved: \",\n status\n )\n )\n );\n\n require(\n result == BET_RESULT.WIN || result == BET_RESULT.DRAW,\n \"Only give winners or draw, no other choices\"\n );\n\n for (uint i = 0; i < betKeys.length; i++) {\n Bet memory bet = bets[betKeys[i]];\n if (\n result == BET_RESULT.WIN &&\n keccak256(bytes(bet.option)) == keccak256(bytes(optionResult))\n ) {\n //WINNER!\n uint256 earnings = Math.mulDiv(\n bet.amount,\n calculateOdds(bet.option, 0),\n 10 ** ODD_DECIMALS\n );\n console.log(\"earnings: %d for %s\", earnings, bet.owner);\n bet.owner.transfer(earnings);\n winner = optionResult;\n } else if (result == BET_RESULT.DRAW) {\n //GIVE BACK MONEY - FEES\n\n uint256 feesAmount = Math.mulDiv(bet.amount, FEES, 100);\n\n (bool success, uint256 moneyBack) = bet.amount.trySub(\n feesAmount\n );\n\n require(success, \"Cannot sub fees amount from amount\");\n\n console.log(\n \"give back money: %d for %s\",\n moneyBack,\n bet.owner\n );\n\n bet.owner.transfer(moneyBack);\n } else {\n //NEXT\n console.log(\"bet lost for %s\", bet.owner);\n }\n }\n\n status = result;\n }\n}\n" - } - } - } -} \ No newline at end of file diff --git a/etherlink-marketpulse/ignition/deployments/chain-127823/deployed_addresses.json b/etherlink-marketpulse/ignition/deployments/chain-127823/deployed_addresses.json deleted file mode 100644 index a3f2807..0000000 --- a/etherlink-marketpulse/ignition/deployments/chain-127823/deployed_addresses.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "MarketpulseModule#Marketpulse": "0xD380bb8E70C0a509C8b904A74258fE57F012e567" -} \ No newline at end of file diff --git a/etherlink-marketpulse/ignition/deployments/chain-127823/journal.jsonl b/etherlink-marketpulse/ignition/deployments/chain-127823/journal.jsonl deleted file mode 100644 index e8880ba..0000000 --- a/etherlink-marketpulse/ignition/deployments/chain-127823/journal.jsonl +++ /dev/null @@ -1,14 +0,0 @@ - -{"chainId":127823,"type":"DEPLOYMENT_INITIALIZE"} -{"artifactId":"MarketpulseModule#Marketpulse","constructorArgs":[],"contractName":"Marketpulse","dependencies":[],"from":"0x45ff91b4bf16ac9907cf4a11436f9ce61be0650d","futureId":"MarketpulseModule#Marketpulse","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","strategyConfig":{},"type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} -{"futureId":"MarketpulseModule#Marketpulse","networkInteraction":{"data":"0x60806040526003805460ff191660021790555f8054336001600160a01b0319909116179055611f62806100315f395ff3fe6080604052600436106100d9575f3560e01c80637a4f4e9c1161007c578063dfbf53ae11610057578063dfbf53ae14610224578063e9c20cb914610238578063f65e65011461024b578063f851a4401461026c575f5ffd5b80637a4f4e9c146101e65780638b7b23ee146100dd578063bb0b644314610205575f5ffd5b8063200d2ed2116100b7578063200d2ed21461014f57806322af00fa146101755780635c36b186146101a45780635e57966d146101ba575f5ffd5b806308888c0a146100dd5780631ccf6955146101045780631d86be8814610130575b5f5ffd5b3480156100e8575f5ffd5b506100f1600a81565b6040519081526020015b60405180910390f35b34801561010f575f5ffd5b5061012361011e36600461175f565b6102a2565b6040516100fb91906117a4565b34801561013b575f5ffd5b506100f161014a366004611890565b6103ac565b34801561015a575f5ffd5b506003546101689060ff1681565b6040516100fb91906118e6565b348015610180575f5ffd5b5061019461018f36600461175f565b610931565b6040516100fb949392919061190c565b3480156101af575f5ffd5b506101b86109ea565b005b3480156101c5575f5ffd5b506101d96101d4366004611946565b610a39565b6040516100fb919061196c565b3480156101f1575f5ffd5b506101b861020036600461197e565b610bf7565b348015610210575f5ffd5b506100f161021f36600461175f565b6110b9565b34801561022f575f5ffd5b506101d96110d8565b6100f16102463660046119d0565b611164565b348015610256575f5ffd5b5061025f61139a565b6040516100fb9190611a42565b348015610277575f5ffd5b505f5461028a906001600160a01b031681565b6040516001600160a01b0390911681526020016100fb565b6102d360405180608001604052805f81526020015f6001600160a01b03168152602001606081526020015f81525090565b5f82815260016020818152604092839020835160808101855281548152928101546001600160a01b031691830191909152600281018054929391929184019161031b90611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461034790611a84565b80156103925780601f1061036957610100808354040283529160200191610392565b820191905f5260205f20905b81548152906001019060200180831161037557829003601f168201915b505050505081526020016003820154815250509050919050565b5f6103d0604051806060016040528060308152602001611edb6030913984846113f0565b5f805b60025481101561057a575f60015f600284815481106103f4576103f4611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161044690611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461047290611a84565b80156104bd5780601f10610494576101008083540402835291602001916104bd565b820191905f5260205f20905b8154815290600101906020018083116104a057829003601f168201915b505050505081526020016003820154815250509050858051906020012081604001518051906020012014610571575f5f61050483606001518661143c90919063ffffffff16565b915091508161056d5760405162461bcd60e51b815260206004820152602a60248201527f43616e6e6f742061646420746f74616c4c6f736572416d6f756e7420616e642060448201526918995d0b985b5bdd5b9d60b21b60648201526084015b60405180910390fd5b9350505b506001016103d3565b506105b1604051806040016040528060148152602001731d1bdd185b131bdcd95c905b5bdd5b9d0e88095960621b81525082611454565b825f5b600254811015610757575f60015f600284815481106105d5576105d5611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161062790611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461065390611a84565b801561069e5780601f106106755761010080835404028352916020019161069e565b820191905f5260205f20905b81548152906001019060200180831161068157829003601f168201915b50505050508152602001600382015481525050905086805190602001208160400151805190602001200361074e575f5f6106e583606001518661143c90919063ffffffff16565b915091508161074a5760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f742061646420746f74616c57696e6e6572416d6f756e7420616e6460448201526a0818995d0b985b5bdd5b9d60aa1b6064820152608401610564565b9350505b506001016105b4565b5061078f604051806040016040528060158152602001741d1bdd185b15da5b9b995c905b5bdd5b9d0e880959605a1b81525082611454565b5f6107a58361079f600a80611bc7565b8461149d565b90506107e66040518060400160405280601881526020017f7061727420706572204f44445f444543494d414c3a202564000000000000000081525082611454565b5f806107fd6107f6600a80611bc7565b849061143c565b91509150816108465760405162461bcd60e51b815260206004820152601560248201527443616e6e6f7420616464207061727420616e64203160581b6044820152606401610564565b61087a604051806040016040528060128152602001711bd9191dda5d1a1bdd5d1199595cce88095960721b81525082611454565b5f806108a8606461088c600a80611bc7565b61089790600a611bd2565b6108a19190611bfd565b849061154d565b91509150816108f95760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f742072656d6f766520666565732066726f6d206f646400000000006044820152606401610564565b610922604051806040016040528060078152602001661bd9190e88095960ca1b81525082611454565b96505050505050505b92915050565b600160208190525f91825260409091208054918101546002820180546001600160a01b03909216929161096390611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461098f90611a84565b80156109da5780601f106109b1576101008083540402835291602001916109da565b820191905f5260205f20905b8154815290600101906020018083116109bd57829003601f168201915b5050505050908060030154905084565b610a0f6040518060400160405280600481526020016350696e6760e01b81525061155d565b6040517f4d015fcc2a20c24d7be893b3a525eac864b5a53a5f88ef7201a600465c73314e905f90a1565b604080518082018252601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151602a808252606082810190945284841b915f91602082018180368337019050509050600360fc1b815f81518110610a9a57610a9a611abc565b60200101906001600160f81b03191690815f1a905350600f60fb1b81600181518110610ac857610ac8611abc565b60200101906001600160f81b03191690815f1a9053505f5b6014811015610bee57836004848360148110610afe57610afe611abc565b1a60f81b6001600160f81b031916901c60f81c60ff1681518110610b2457610b24611abc565b01602001516001600160f81b03191682610b3f836002611bd2565b610b4a906002611c1c565b81518110610b5a57610b5a611abc565b60200101906001600160f81b03191690815f1a90535083838260148110610b8357610b83611abc565b825191901a600f16908110610b9a57610b9a611abc565b01602001516001600160f81b03191682610bb5836002611bd2565b610bc0906003611c1c565b81518110610bd057610bd0611abc565b60200101906001600160f81b03191690815f1a905350600101610ae0565b50949350505050565b5f546001600160a01b031633811490610c0f90610a39565b604051602001610c1f9190611c2f565b60405160208183030381529060405290610c4c5760405162461bcd60e51b8152600401610564919061196c565b50600260035460ff166002811115610c6657610c666118d2565b6003546040519290911491610c819160ff1690602001611c7d565b60405160208183030381529060405290610cae5760405162461bcd60e51b8152600401610564919061196c565b505f816002811115610cc257610cc26118d2565b1480610cdf57506001816002811115610cdd57610cdd6118d2565b145b610d3f5760405162461bcd60e51b815260206004820152602b60248201527f4f6e6c7920676976652077696e6e657273206f7220647261772c206e6f206f7460448201526a6865722063686f6963657360a81b6064820152608401610564565b5f5b600254811015611090575f60015f60028481548110610d6257610d62611abc565b5f9182526020808320909101548352828101939093526040918201902081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191610db490611a84565b80601f0160208091040260200160405190810160405280929190818152602001828054610de090611a84565b8015610e2b5780601f10610e0257610100808354040283529160200191610e2b565b820191905f5260205f20905b815481529060010190602001808311610e0e57829003601f168201915b50505091835250506003919091015460209091015290505f836002811115610e5557610e556118d2565b148015610e7357508380519060200120816040015180519060200120145b15610f29575f610e9f8260600151610e8f84604001515f6103ac565b610e9a600a80611bc7565b61149d565b9050610edb604051806040016040528060138152602001726561726e696e67733a20256420666f7220257360681b8152508284602001516115a3565b81602001516001600160a01b03166108fc8290811502906040515f60405180830381858888f19350505050158015610f15573d5f5f3e3d5ffd5b506004610f228682611d32565b5050611087565b6001836002811115610f3d57610f3d6118d2565b03611052575f610f548260600151600a606461149d565b90505f5f610f6f83856060015161154d90919063ffffffff16565b9150915081610fcb5760405162461bcd60e51b815260206004820152602260248201527f43616e6e6f7420737562206665657320616d6f756e742066726f6d20616d6f756044820152611b9d60f21b6064820152608401610564565b61100f6040518060400160405280601a81526020017f67697665206261636b206d6f6e65793a20256420666f722025730000000000008152508286602001516115a3565b83602001516001600160a01b03166108fc8290811502906040515f60405180830381858888f19350505050158015611049573d5f5f3e3d5ffd5b50505050611087565b6110876040518060400160405280600f81526020016e626574206c6f737420666f7220257360881b81525082602001516115ea565b50600101610d41565b506003805482919060ff191660018360028111156110b0576110b06118d2565b02179055505050565b600281815481106110c8575f80fd5b5f91825260209091200154905081565b600480546110e590611a84565b80601f016020809104026020016040519081016040528092919081815260200182805461111190611a84565b801561115c5780601f106111335761010080835404028352916020019161115c565b820191905f5260205f20905b81548152906001019060200180831161113f57829003601f168201915b505050505081565b5f5f34116111b45760405162461bcd60e51b815260206004820152601c60248201527f42657420616d6f756e74206d75737420626520706f7369746976652e000000006044820152606401610564565b33313411156112155760405162461bcd60e51b815260206004820152602760248201527f496e73756666696369656e742062616c616e636520746f20706c61636520746860448201526634b9903132ba1760c91b6064820152608401610564565b5f61121e61162f565b90506040518060800160405280828152602001336001600160a01b0316815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920182905250938552505034602093840152508381526001808352604091829020845181559284015190830180546001600160a01b0319166001600160a01b0390921691909117905582015160028201906112c69082611d32565b5060609190910151600390910155600280546001810182555f919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0181905560408051808201909152600d81526c10995d080959081c1b1858d959609a1b60208201526113369082611454565b611390604051806060016040528060228152602001611f0b602291393487878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508992506116bb915050565b90505b9392505050565b606060028054806020026020016040519081016040528092919081815260200182805480156113e657602002820191905f5260205f20905b8154815260200190600101908083116113d2575b5050505050905090565b61143783838360405160240161140893929190611ded565b60408051601f198184030181529190526020810180516001600160e01b0316635821efa160e01b17905261170a565b505050565b80820182811015905f90825b81029150509250929050565b611499828260405160240161146a929190611e22565b60408051601f198184030181529190526020810180516001600160e01b0316632d839cb360e21b17905261170a565b5050565b5f5f5f6114aa8686611713565b91509150815f036114ce578381816114c4576114c4611be9565b0492505050611393565b8184116114e5576114e5600385150260111861172f565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b80820382811115905f9082611448565b6115a081604051602401611571919061196c565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b17905261170a565b50565b6114378383836040516024016115bb93929190611e43565b60408051601f198184030181529190526020810180516001600160e01b031663038fd88960e31b17905261170a565b6114998282604051602401611600929190611e75565b60408051601f198184030181529190526020810180516001600160e01b031663319af33360e01b17905261170a565b5f6116666040518060400160405280601581526020017410d85b1b1a5b99c819d95b995c985d1950995d1259605a1b81525061155d565b42443360405160200161169e93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b604051602081830303815290604052805190602001205f1c905090565b611704848484846040516024016116d59493929190611e9e565b60408051601f198184030181529190526020810180516001600160e01b031663c67ea9d160e01b17905261170a565b50505050565b6115a081611740565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5f6a636f6e736f6c652e6c6f6790505f5f835160208501845afa505050565b5f6020828403121561176f575f5ffd5b5035919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081528151602082015260018060a01b0360208301511660408201525f6040830151608060608401526117db60a0840182611776565b9050606084015160808401528091505092915050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112611814575f5ffd5b813567ffffffffffffffff81111561182e5761182e6117f1565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561185d5761185d6117f1565b604052818152838201602001851015611874575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f604083850312156118a1575f5ffd5b823567ffffffffffffffff8111156118b7575f5ffd5b6118c385828601611805565b95602094909401359450505050565b634e487b7160e01b5f52602160045260245ffd5b602081016003831061190657634e487b7160e01b5f52602160045260245ffd5b91905290565b8481526001600160a01b03841660208201526080604082018190525f9061193590830185611776565b905082606083015295945050505050565b5f60208284031215611956575f5ffd5b81356001600160a01b0381168114611393575f5ffd5b602081525f6113936020830184611776565b5f5f6040838503121561198f575f5ffd5b823567ffffffffffffffff8111156119a5575f5ffd5b6119b185828601611805565b9250506020830135600381106119c5575f5ffd5b809150509250929050565b5f5f5f604084860312156119e2575f5ffd5b833567ffffffffffffffff8111156119f8575f5ffd5b8401601f81018613611a08575f5ffd5b803567ffffffffffffffff811115611a1e575f5ffd5b866020828401011115611a2f575f5ffd5b6020918201979096509401359392505050565b602080825282518282018190525f918401906040840190835b81811015611a79578351835260209384019390920191600101611a5b565b509095945050505050565b600181811c90821680611a9857607f821691505b602082108103611ab657634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b6001815b6001841115611b1f57808504811115611b0357611b03611ad0565b6001841615611b1157908102905b60019390931c928002611ae8565b935093915050565b5f82611b355750600161092b565b81611b4157505f61092b565b8160018114611b575760028114611b6157611b7d565b600191505061092b565b60ff841115611b7257611b72611ad0565b50506001821b61092b565b5060208310610133831016604e8410600b8410161715611ba0575081810a61092b565b611bac5f198484611ae4565b805f1904821115611bbf57611bbf611ad0565b029392505050565b5f6113938383611b27565b808202811582820484141761092b5761092b611ad0565b634e487b7160e01b5f52601260045260245ffd5b5f82611c1757634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561092b5761092b611ad0565b6e027b7363c903a34329030b236b4b71608d1b81525f82518060208501600f85015e741031b0b71033b4bb32903a3432903932b9bab63a1760591b600f939091019283015250602401919050565b7f526573756c7420697320616c726561647920676976656e20616e64206265747381526e01030b932903932b9b7b63b32b21d1608d1b60208201525f60038310611cd557634e487b7160e01b5f52602160045260245ffd5b5060f89190911b602f82015260300190565b601f82111561143757805f5260205f20601f840160051c81016020851015611d0c5750805b601f840160051c820191505b81811015611d2b575f8155600101611d18565b5050505050565b815167ffffffffffffffff811115611d4c57611d4c6117f1565b611d6081611d5a8454611a84565b84611ce7565b6020601f821160018114611d92575f8315611d7b5750848201515b5f19600385901b1c1916600184901b178455611d2b565b5f84815260208120601f198516915b82811015611dc15787850151825560209485019460019092019101611da1565b5084821015611dde57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b606081525f611dff6060830186611776565b8281036020840152611e118186611776565b915050826040830152949350505050565b604081525f611e346040830185611776565b90508260208301529392505050565b606081525f611e556060830186611776565b6020830194909452506001600160a01b0391909116604090910152919050565b604081525f611e876040830185611776565b905060018060a01b03831660208301529392505050565b608081525f611eb06080830187611776565b8560208401528281036040840152611ec88186611776565b9150508260608301529594505050505056fe63616c63756c6174654f64647320666f72206f7074696f6e20257320616e642062657420616d6f756e7420697320256442657420706c616365643a202564206f6e202573206174206f646473206f66202564a2646970667358221220fb0f6d0e172fc4eade4bcff36b8f9da560c1f669edccdbbfddc82c5b6d7510d064736f6c634300081c0033","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"MarketpulseModule#Marketpulse","networkInteractionId":1,"nonce":91,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"MarketpulseModule#Marketpulse","networkInteractionId":1,"nonce":91,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2000000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0xb6dfaa70845d60ef05c52defe4ff8a59c051c6ea60b79a3e07dd1a0c33a7bc48"},"type":"TRANSACTION_SEND"} -{"futureId":"MarketpulseModule#Marketpulse","hash":"0xb6dfaa70845d60ef05c52defe4ff8a59c051c6ea60b79a3e07dd1a0c33a7bc48","networkInteractionId":1,"receipt":{"blockHash":"0x9ad1f5c1eea83584d3702623a7894bba359c5b9cb40200b18b941c78a87fff7d","blockNumber":1519077,"contractAddress":"0xD380bb8E70C0a509C8b904A74258fE57F012e567","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"MarketpulseModule#Marketpulse","result":{"address":"0xD380bb8E70C0a509C8b904A74258fE57F012e567","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} -{"args":[],"artifactId":"MarketpulseModule#Marketpulse","contractAddress":"0xD380bb8E70C0a509C8b904A74258fE57F012e567","dependencies":["MarketpulseModule#Marketpulse"],"from":"0x45ff91b4bf16ac9907cf4a11436f9ce61be0650d","functionName":"ping","futureId":"MarketpulseModule#Marketpulse.ping","strategy":"basic","strategyConfig":{},"type":"CALL_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"0"}} -{"futureId":"MarketpulseModule#Marketpulse.ping","networkInteraction":{"data":"0x5c36b186","id":1,"to":"0xD380bb8E70C0a509C8b904A74258fE57F012e567","type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"0"}},"type":"NETWORK_INTERACTION_REQUEST"} -{"futureId":"MarketpulseModule#Marketpulse.ping","networkInteractionId":1,"nonce":92,"type":"TRANSACTION_PREPARE_SEND"} -{"futureId":"MarketpulseModule#Marketpulse.ping","networkInteractionId":1,"nonce":92,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2000000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"0"}},"hash":"0xf93bce73fd8b107a4655c2ac7cdbdc249c58a9f2faa4d5be710a80381f135676"},"type":"TRANSACTION_SEND"} -{"futureId":"MarketpulseModule#Marketpulse.ping","hash":"0xf93bce73fd8b107a4655c2ac7cdbdc249c58a9f2faa4d5be710a80381f135676","networkInteractionId":1,"receipt":{"blockHash":"0x4613390bffe5b1ea92cb232a8dac6e0340a18c991dc2dff2417290c037270788","blockNumber":1519083,"logs":[{"address":"0xD380bb8E70C0a509C8b904A74258fE57F012e567","data":"0x","logIndex":0,"topics":["0x4d015fcc2a20c24d7be893b3a525eac864b5a53a5f88ef7201a600465c73314e"]}],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} -{"futureId":"MarketpulseModule#Marketpulse.ping","result":{"type":"SUCCESS"},"type":"CALL_EXECUTION_STATE_COMPLETE"} \ No newline at end of file diff --git a/etherlink-marketpulse/ignition/modules/Marketpulse.ts b/etherlink-marketpulse/ignition/modules/Marketpulse.ts deleted file mode 100644 index 9c7ade8..0000000 --- a/etherlink-marketpulse/ignition/modules/Marketpulse.ts +++ /dev/null @@ -1,14 +0,0 @@ -// This setup uses Hardhat Ignition to manage smart contract deployments. -// Learn more about it at https://hardhat.org/ignition - -import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; - -const MarketpulseModule = buildModule("MarketpulseModule", (m) => { - const MarketpulseContract = m.contract("Marketpulse", []); - - m.call(MarketpulseContract, "ping", []); - - return { MarketpulseContract }; -}); - -export default MarketpulseModule; diff --git a/etherlink-marketpulse/package.json b/etherlink-marketpulse/package.json deleted file mode 100644 index ce60da5..0000000 --- a/etherlink-marketpulse/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "marketpulse-shadownet", - "version": "1.0.0", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "description": "", - "devDependencies": { - "@nomicfoundation/hardhat-ignition": "^3.0.6", - "@nomicfoundation/hardhat-toolbox-viem": "^5.0.1", - "@nomicfoundation/hardhat-verify": "^3.0.8", - "@types/chai": "^5.2.3", - "@types/node": "^22.19.3", - "chai": "^6.2.2", - "forge-std": "github:foundry-rs/forge-std#v1.9.4", - "hardhat": "^3.1.2", - "ts-node": "^10.9.2", - "typescript": "~5.8.0", - "viem": "^2.43.5" - }, - "type": "module", - "dependencies": { - "@openzeppelin/contracts": "^5.4.0" - } -} diff --git a/etherlink-marketpulse/test/Marketpulse.ts b/etherlink-marketpulse/test/Marketpulse.ts deleted file mode 100644 index 1e00a55..0000000 --- a/etherlink-marketpulse/test/Marketpulse.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { expect } from "chai"; -import hre from "hardhat"; -import { ContractFunctionExecutionError, parseEther } from "viem"; -import { describe, it } from "node:test"; -const { viem, networkHelpers } = await hre.network.connect(); - -//constants and local variables -const ODD_DECIMALS = 10; -let initAliceAmount = 0n; -let initBobAmount = 0n; - -//Enum definition copy/pasta from Solidity code -enum BET_RESULT { - WIN = 0, - DRAW = 1, - PENDING = 2, -} - -describe("Marketpulse", function () { - // We define a fixture to reuse the same setup in every test. - // We use loadFixture to run this setup once, snapshot that state, - // and reset Hardhat Network to that snapshot in every test. - async function deployContractFixture() { - // Contracts are deployed using the first signer/account by default - const [owner, bob] = await viem.getWalletClients(); - - // Set block base fee to zero because we want exact calculation checks without network fees - await networkHelpers.setNextBlockBaseFeePerGas("0x0"); - - const marketpulseContract = await viem.deployContract( - "Marketpulse", - [] - ); - - const publicClient = await viem.getPublicClient(); - - initAliceAmount = await publicClient.getBalance({ - address: owner.account.address, - }); - - initBobAmount = await publicClient.getBalance({ - address: bob.account.address, - }); - - return { - marketpulseContract, - owner, - bob, - publicClient, - }; - } - - describe("init function", function () { - it("should be initialized", async function () { - const { marketpulseContract, owner } = await networkHelpers.loadFixture( - deployContractFixture - ); - - const ownerFromStorage = await marketpulseContract.read.admin(); - console.log("ownerFromStorage", ownerFromStorage); - expect(ownerFromStorage.toLowerCase()).to.equal( - owner.account.address.toLowerCase() - ); //trick to remove capital letters - }); - - it("should return Pong", async function () { - const { marketpulseContract, publicClient } = await networkHelpers.loadFixture( - deployContractFixture - ); - - await marketpulseContract.write.ping({ gasPrice: 0n }); - - const logs = await publicClient.getContractEvents({ - abi: marketpulseContract.abi, - eventName: "Pong", - }); - console.log(logs); - expect(logs.length).to.equal(1); - }); - }); - - // BET SCENARIO - - //full scenario should be contained inside the same 'it' , otherwise the full context is reset - describe("scenario", () => { - let betChiefs1Id: bigint = BigInt(0); - let betLions2Id: string = ""; - let betKeys: bigint[] = []; - - it("should run the full scenario correctly", async () => { - console.log("Initialization should return a list of empty bets"); - const { - marketpulseContract, - owner: alice, - publicClient, - bob, - } = await networkHelpers.loadFixture(deployContractFixture); - - expect(await marketpulseContract.read.betKeys.length).to.equal(0); - - console.log("Chiefs bet for 1 ether should return a hash"); - - const betChiefs1IdHash = await marketpulseContract.write.bet( - ["chiefs", parseEther("1")], - { value: parseEther("1"), gasPrice: 0n } - ); - expect(betChiefs1IdHash).not.null; - - // Wait for the transaction receipt - let receipt = await publicClient.waitForTransactionReceipt({ - hash: betChiefs1IdHash, - }); - - expect(receipt.status).equals("success"); - - betKeys = [...(await marketpulseContract.read.getBetKeys())]; - console.log("betKeys", betKeys); - - betChiefs1Id = betKeys[0]; - - console.log("Should find the Chiefs bet from hash"); - - const betChiefs1 = await marketpulseContract.read.getBets([betChiefs1Id]); - - expect(betChiefs1).not.null; - - expect(betChiefs1.owner.toLowerCase()).equals( - alice.account.address.toLowerCase() - ); - expect(betChiefs1.option).equals("chiefs"); - expect(betChiefs1.amount).equals(parseEther("1")); - - console.log("Should get a correct odd of 0.9 (including fees) for Chiefs if we bet 1"); - - let odd = await marketpulseContract.read.calculateOdds([ - "chiefs", - parseEther("1"), - ]); - - expect(odd).equals(BigInt(Math.floor(0.9 * 10 ** ODD_DECIMALS))); //rounding - - console.log("Lions bet for 2 ethers should return a hash"); - - // Set block base fee to zero - await networkHelpers.setNextBlockBaseFeePerGas("0x0"); - - const betLions2IdHash = await marketpulseContract.write.bet( - ["lions", parseEther("2")], - { value: parseEther("2"), account: bob.account.address, gasPrice: 0n } - ); - expect(betLions2IdHash).not.null; - - // Wait for the transaction receipt - receipt = await publicClient.waitForTransactionReceipt({ - hash: betLions2IdHash, - }); - - expect(receipt.status).equals("success"); - - betKeys = [...(await marketpulseContract.read.getBetKeys())]; - console.log("betKeys", betKeys); - - const betLions2Id = betKeys[1]; - - console.log("Should find the Lions bet from hash"); - - const betLions2 = await marketpulseContract.read.getBets([ - betLions2Id, - ]); - - expect(betLions2).not.null; - - expect(betLions2.owner.toLowerCase()).equals( - bob.account.address.toLowerCase() - ); - expect(betLions2.option).equals("lions"); - expect(betLions2.amount).equals(parseEther("2")); - - console.log("Should get a correct odd of 1.9 for Chiefs (including fees) if we bet 1"); - - odd = await marketpulseContract.read.calculateOdds([ - "chiefs", - parseEther("1"), - ]); - - expect(odd).equals(BigInt(Math.floor(1.9 * 10 ** ODD_DECIMALS))); - - console.log( - "Should get a correct odd of 1.23333 for lions (including fees) if we bet 1" - ); - - odd = await marketpulseContract.read.calculateOdds([ - "lions", - parseEther("1"), - ]); - - expect(odd).equals( - BigInt(Math.floor((1 + 1 / 3 - 0.1) * 10 ** ODD_DECIMALS)) - ); - - console.log("Should return all correct balances after resolving Win on Chiefs"); - - await marketpulseContract.write.resolveResult( - ["chiefs", BET_RESULT.WIN], - { gasPrice: 0n } - ); - - expect( - await publicClient.getBalance({ - address: marketpulseContract.address, - }) - ).equals(parseEther("0.1")); - expect( - await publicClient.getBalance({ address: alice.account.address }) - ).equals(initAliceAmount + parseEther("1.9")); // -1+2.9 - - expect( - await publicClient.getBalance({ address: bob.account.address }) - ).equals(initBobAmount - parseEther("2")); //-2 - - console.log("Should have state finalized after resolution"); - - const result = await marketpulseContract.read.status(); - expect(result).not.null; - expect(result).equals(BET_RESULT.WIN); - - console.log("Should return an error if we try to resolve results again"); - - try { - await marketpulseContract.write.resolveResult( - ["chiefs", BET_RESULT.WIN], - { gasPrice: 0n } - ); - } catch (e) { - expect((e as ContractFunctionExecutionError).details).contains( - "VM Exception while processing transaction: reverted with reason string 'Result is already given and bets are resolved" - ); - } - }); - }); -}); diff --git a/etherlink-prediction/README.md b/etherlink-prediction/README.md new file mode 100644 index 0000000..0708f6a --- /dev/null +++ b/etherlink-prediction/README.md @@ -0,0 +1,3 @@ +# Tutorial application: Create a prediction market on Etherlink + +This is the completed application from the tutorial [Create a prediction market on Etherlink](https://docs.etherlink.com/tutorials/predictionMarket/). diff --git a/etherlink-prediction/backend/.env.example b/etherlink-prediction/backend/.env.example new file mode 100644 index 0000000..aa11ba6 --- /dev/null +++ b/etherlink-prediction/backend/.env.example @@ -0,0 +1 @@ +PRIVATE_KEY=0xETHERLINK_PRIVATE_KEY diff --git a/etherlink-marketpulse/.gitignore b/etherlink-prediction/backend/.gitignore similarity index 100% rename from etherlink-marketpulse/.gitignore rename to etherlink-prediction/backend/.gitignore diff --git a/etherlink-prediction/backend/contracts/Contract.sol b/etherlink-prediction/backend/contracts/Contract.sol new file mode 100644 index 0000000..7ffd076 --- /dev/null +++ b/etherlink-prediction/backend/contracts/Contract.sol @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.24; + +// for creating a contract that can be owned by an address +// this is useful for managing access permissions to methods in the contract +import "@openzeppelin/contracts/access/Ownable.sol"; + +// for preventing reentrancy attacks on functions that modify state +// this is important for functions that involve transferring tokens or ether +// to ensure that the function cannot be called again while it is still executing +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +/** @title A simple prediction market that uses the Pari-mutuel model allowing winners to share the prize pool. + */ + +contract PredictxtzContract is Ownable, ReentrancyGuard { + // This contract allows users to create markets, place bets, resolve markets, and claim winnings. + + constructor() Ownable(msg.sender) {} + + // constants + uint256 public constant PRECISION = 1e18; + uint256 public constant VIRTUAL_LIQUIDITY = 1000 * PRECISION; // used to calculate price per share + + // holds information about each market + struct Market { + uint256 id; + string question; + // string description; + uint256 endTime; // When betting stops + // uint256 resolveTime; // When market can be resolved. // For now, we resolve immediately after endTime or manually + bool resolved; + uint8 winner; // 0 = NO, 1 = YES, 2 = INVALID + uint256 totalYesAmount; // Total $ bet on YES + uint256 totalNoAmount; // Total $ bet on NO + uint256 totalYesShares; // Total YES shares (for price calculation) + uint256 totalNoShares; // Total No shares (for price calculation) + uint256 marketBalance; // how much is in the market + address creator; + // uint256 createdAt; + bool active; + } + + // calculates the total position held by a market participant + struct Position { + uint256 yesAmount; // $ amount bet on YES + uint256 noAmount; // $ amount bet on NO + uint256 yesShares; // YES shares owned (for pool splitting) + uint256 noShares; // NO shares owned (for pool splitting) + bool claimed; // Whether winnings have been claimed + } + + uint256 public marketCounter; // keeps track of the no of markets created + + mapping(uint256 => Market) public markets; + mapping(uint256 => mapping(address => Position)) public positions; + mapping(address => uint256[]) public userMarkets; + + // events + event MarketCreated( + uint256 indexed marketId, + address indexed creator, + string question, + uint256 endTime + ); + + event BetPlaced( + uint256 indexed marketId, + address indexed user, + bool indexed isYes, + uint256 amount, + uint256 shares + ); + + event MarketResolved( + uint256 indexed marketId, + uint8 indexed winner, + address indexed resolver + ); + + event WinningsClaimed( + uint256 indexed marketId, + address indexed user, + uint256 amount + ); + + function createMarket( + string calldata question, + uint256 duration + ) external returns (uint256) { + require(duration > 0, "Duration must be positive"); + require(bytes(question).length > 0, "Question cannot be empty"); + + uint256 marketId = ++marketCounter; + + markets[marketId] = Market({ + id: marketId, + question: question, + endTime: block.timestamp + duration, + resolved: false, + winner: 2, // Unresolved + totalYesAmount: 0, // No money in pool yet + totalNoAmount: 0, // No money in pool yet + totalYesShares: VIRTUAL_LIQUIDITY, // Virtual shares for pricing + totalNoShares: VIRTUAL_LIQUIDITY, // Virtual shares for pricing + marketBalance: 0, + creator: msg.sender, + // createdAt: block.timestamp, + active: true + }); + + // emiting events makes it cheaper to track changes in the contract without needing to read the entire state and paying gas + emit MarketCreated( + marketId, + msg.sender, + question, + block.timestamp + duration + ); + return marketId; + } + + /** + * Calculate pricePerShare without fees + */ + function pricePerShareWithoutFees( + uint256 marketId, + bool isYes + ) public view returns (uint256) { + Market memory market = markets[marketId]; + uint256 totalShares = market.totalYesShares + market.totalNoShares; + + if (isYes) { + return (market.totalYesShares * PRECISION) / totalShares; + } else { + return (market.totalNoShares * PRECISION) / totalShares; + } + } + + /** + * Calculate how many shares you get for a bet amount + * More money = more shares = bigger portion of winnings + */ + function calculateShares( + uint256 marketId, + bool isYes, + uint256 betAmount + ) public view returns (uint256) { + Market memory market = markets[marketId]; + require(market.active, "Market not active"); + + // The share price is now calculated without fees + uint256 pricePerShare = pricePerShareWithoutFees(marketId, isYes); + uint256 shares = (betAmount * PRECISION) / pricePerShare; + return shares; + } + + // BETTING FUNCTIONS + + /** + * @dev Place a bet on YES or NO + * @param marketId The market to bet on + * @param isYes true for a bet on YES, false for a bet on NO + */ + function placeBet( + uint256 marketId, + bool isYes + ) external payable nonReentrant { + Market storage market = markets[marketId]; + uint256 betAmount = msg.value; // Use the value sent with the transaction as the bet amount + market.marketBalance += msg.value; + + // Validation + require(market.active, "Market not active"); + require(!market.resolved, "Market has been resolved"); + require(block.timestamp < market.endTime, "Betting period ended"); + require(betAmount > 0, "Must bet positive amount"); + + uint256 shares = calculateShares(marketId, isYes, betAmount); // 100shares when amount = $51 + + // Update market totals + if (isYes) { + market.totalYesAmount += betAmount; // Tracks the total amount bet on YES + market.totalYesShares += shares; // Synthetic YES shares (virtual liquidity) + Real YES shares + positions[marketId][msg.sender].yesAmount += betAmount; // Tracks user's YES bet amount + positions[marketId][msg.sender].yesShares += shares; // Tracks user's YES shares + } else { + market.totalNoAmount += betAmount; + market.totalNoShares += shares; + positions[marketId][msg.sender].noAmount += betAmount; + positions[marketId][msg.sender].noShares += shares; + } + + // Track user participation + if ( + positions[marketId][msg.sender].yesAmount + + positions[marketId][msg.sender].noAmount == + betAmount + ) { + userMarkets[msg.sender].push(marketId); + } + + emit BetPlaced(marketId, msg.sender, isYes, betAmount, shares); + } + + // Only the owner can resolve markets + function resolveMarket(uint256 marketId, uint8 winner) external onlyOwner { + Market storage market = markets[marketId]; + + require(!market.resolved, "Already resolved"); + require(winner <= 2, "Invalid winner"); + + market.resolved = true; + market.active = false; + market.winner = winner; + + emit MarketResolved(marketId, winner, msg.sender); + } + + // CLAIMING WINNINGS + + /** + * @dev Claim winnings from a resolved market + * Winners split the total pool proportionally to their shares + */ + function claimWinnings(uint256 marketId) external nonReentrant { + Market storage market = markets[marketId]; //access storage so we can update + Position storage position = positions[marketId][msg.sender]; + + require(market.resolved, "Market not resolved"); + require(!position.claimed, "Already claimed"); + + position.claimed = true; + + uint256 payout = 0; + + if (market.winner == 2) { + // INVALID - refund original bets + payout = position.yesAmount + position.noAmount; + } else if (market.winner == 1 && position.yesShares > 0) { + // YES wins - split the total pool among YES shareholders + uint256 totalPool = market.totalYesAmount + market.totalNoAmount; + uint256 winningSideShares = market.totalYesShares - + VIRTUAL_LIQUIDITY; // Remove virtual liquidity + + if (winningSideShares > 0) { + payout = (position.yesShares * totalPool) / winningSideShares; + } + } else if (market.winner == 0 && position.noShares > 0) { + // NO wins - split the total pool among NO shareholders + uint256 totalPool = market.totalYesAmount + market.totalNoAmount; + uint256 winningSideShares = market.totalNoShares - + VIRTUAL_LIQUIDITY; // Remove virtual liquidity + + if (winningSideShares > 0) { + payout = (position.noShares * totalPool) / winningSideShares; + } + } + + if (payout > 0) { + (bool success, ) = payable(msg.sender).call{value: payout}(""); + market.marketBalance -= payout; + require(success, "XTZ transfer failed"); + emit WinningsClaimed(marketId, msg.sender, payout); + } + } + + // VIEW FUNCTIONS + + function getUserPosition( + uint256 marketId, + address user + ) external view returns (Position memory) { + return positions[marketId][user]; + } + + function getUserMarkets( + address user + ) external view returns (uint256[] memory) { + return userMarkets[user]; + } + + function getMarket(uint256 marketId) external view returns (Market memory) { + return markets[marketId]; + } + + // Useful for the frontend to know the most recent probabilities for each outcome + function getProbability( + uint256 marketId, + bool isYes + ) external view returns (uint256) { + uint256 price = pricePerShareWithoutFees(marketId, isYes); + return (price * 100) / PRECISION; // get the percentage probability + } +} diff --git a/etherlink-prediction/backend/hardhat.config.ts b/etherlink-prediction/backend/hardhat.config.ts new file mode 100644 index 0000000..9fc4e28 --- /dev/null +++ b/etherlink-prediction/backend/hardhat.config.ts @@ -0,0 +1,26 @@ +import dotenv from 'dotenv'; +dotenv.config(); + +import hardhatViem from "@nomicfoundation/hardhat-viem"; + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + plugins: [ + hardhatViem, + ], + solidity: "0.8.24", + networks: { + etherlinkShadownet: { + type: 'http', + url: "https://node.shadownet.etherlink.com", + chainId: 127823, + accounts: [process.env.PRIVATE_KEY], + }, + etherlinkSandbox: { + type: 'http', + url: "http://localhost:8545", + chainId: 127823, + accounts: [process.env.PRIVATE_KEY], + }, + }, +}; diff --git a/etherlink-marketpulse/package-lock.json b/etherlink-prediction/backend/package-lock.json similarity index 87% rename from etherlink-marketpulse/package-lock.json rename to etherlink-prediction/backend/package-lock.json index df5ac26..db77ba4 100644 --- a/etherlink-marketpulse/package-lock.json +++ b/etherlink-prediction/backend/package-lock.json @@ -1,28 +1,26 @@ { - "name": "marketpulse-shadownet-nic", + "name": "etherlink-prediction-backend", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "marketpulse-shadownet-nic", + "name": "adebola-etherlink-from-scratch-4", "version": "1.0.0", "license": "ISC", "dependencies": { - "@openzeppelin/contracts": "^5.4.0" + "@nomicfoundation/hardhat-viem": "^3.0.1", + "@openzeppelin/contracts": "^5.4.0", + "dotenv": "^17.2.3" }, "devDependencies": { "@nomicfoundation/hardhat-ignition": "^3.0.6", "@nomicfoundation/hardhat-toolbox-viem": "^5.0.1", - "@nomicfoundation/hardhat-verify": "^3.0.8", - "@types/chai": "^5.2.3", - "@types/node": "^22.19.3", - "chai": "^6.2.2", + "@types/node": "^22.19.7", "forge-std": "github:foundry-rs/forge-std#v1.9.4", - "hardhat": "^3.1.2", - "ts-node": "^10.9.2", + "hardhat": "^3.1.4", "typescript": "~5.8.0", - "viem": "^2.43.5" + "viem": "^2.44.4" } }, "node_modules/@actions/core": { @@ -89,19 +87,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -109,7 +94,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -126,7 +110,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -143,7 +126,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -160,7 +142,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -177,7 +158,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -194,7 +174,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -211,7 +190,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -228,7 +206,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -245,7 +222,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -262,7 +238,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -279,7 +254,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -296,7 +270,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -313,7 +286,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -330,7 +302,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -347,7 +318,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -364,7 +334,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -381,7 +350,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -398,7 +366,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -415,7 +382,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -432,7 +398,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -449,7 +414,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -466,7 +430,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -483,7 +446,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -500,7 +462,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -517,7 +478,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -534,7 +494,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -560,6 +519,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/address": "^5.8.0", "@ethersproject/bignumber": "^5.8.0", @@ -588,6 +548,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", @@ -614,6 +575,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/abstract-provider": "^5.8.0", "@ethersproject/bignumber": "^5.8.0", @@ -638,6 +600,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", @@ -662,6 +625,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bytes": "^5.8.0" } @@ -724,6 +688,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bignumber": "^5.8.0" } @@ -744,6 +709,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/abstract-signer": "^5.8.0", "@ethersproject/address": "^5.8.0", @@ -810,6 +776,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/logger": "^5.8.0" } @@ -830,6 +797,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/logger": "^5.8.0" } @@ -871,6 +839,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bytes": "^5.8.0", "@ethersproject/logger": "^5.8.0", @@ -896,6 +865,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bytes": "^5.8.0", "@ethersproject/constants": "^5.8.0", @@ -918,6 +888,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/address": "^5.8.0", "@ethersproject/bignumber": "^5.8.0", @@ -946,6 +917,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/base64": "^5.8.0", "@ethersproject/bytes": "^5.8.0", @@ -979,34 +951,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@noble/ciphers": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz", @@ -1025,7 +969,6 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "1.4.0" @@ -1038,7 +981,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 16" @@ -1048,89 +990,81 @@ } }, "node_modules/@nomicfoundation/edr": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.12.0-next.21.tgz", - "integrity": "sha512-j4DXqk/b2T1DK3L/YOZtTjwXqr/as4n+eKulu3KGVxyzOv2plZqTv9WpepQSejc0298tk/DBdMVwqzU3sd8CAA==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.12.0-next.22.tgz", + "integrity": "sha512-JigYWf2stjpDxSndBsxRoobQHK8kz4SAVaHtTIKQLIHbsBwymE8i120Ejne6Jk+Ndc5CsNINXB8/bK6vLPe9jA==", "license": "MIT", "dependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.21", - "@nomicfoundation/edr-darwin-x64": "0.12.0-next.21", - "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.21", - "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.21", - "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.21", - "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.21", - "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.21" + "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.22", + "@nomicfoundation/edr-darwin-x64": "0.12.0-next.22", + "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.22", + "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.22", + "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.22", + "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.22", + "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.22" }, "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.12.0-next.21.tgz", - "integrity": "sha512-WUBBIlhW9UcYhEKlpuG+A/9gQsTciWID+shi2p5iYzArIZAHssyuUGOZF+z5/KQTyAC+GRQd/2YvCQacNnpOIg==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.12.0-next.22.tgz", + "integrity": "sha512-TpEBSKyMZJEPvYwBPYclC2b+qobKjn1YhVa7aJ1R7RMPy5dJ/PqsrUK5UuUFFybBqoIorru5NTcsyCMWP5T/Fg==", "license": "MIT", "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.12.0-next.21.tgz", - "integrity": "sha512-DOLp9TS3pRxX5OVqH2SMv/hLmo2XZcciO+PLaoXcJGMTmUqDJbc1kOS7+e/kvf+f12e2Y4b/wPQGXKGRgcx61w==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.12.0-next.22.tgz", + "integrity": "sha512-aK/+m8xUkR4u+czTVGU06nSFVH43AY6XCBoR2YjO8SglAAjCSTWK3WAfVb6FcsriMmKv4PrvoyHLMbMP+fXcGA==", "license": "MIT", "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.12.0-next.21.tgz", - "integrity": "sha512-yYLkOFA9Y51TdHrZIFM6rLzArw/iEQuIGwNnTRUXVBO1bNyKVxfaO7qg4WuRSNWKuZAtMawilcjoyHNuxzm/oQ==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.12.0-next.22.tgz", + "integrity": "sha512-W5vXMleG14hVzRYGPEwlHLJ6iiQE8Qh63Uj538nAz4YUI6wWSgUOZE7K2Gt1EdujZGnrt7kfDslgJ96n4nKQZw==", "license": "MIT", "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.12.0-next.21.tgz", - "integrity": "sha512-/L2hJYoUSHG9RTZRfOfYfsEBo1I30EQt3M+kWTDCS09jITnotWbqS9H/qbjd8u+8/xBBtAxNFhBgrIYu0GESSw==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.12.0-next.22.tgz", + "integrity": "sha512-VDp7EB3iY8MH/fFVcgEzLDGYmtS6j2honNc0RNUCFECKPrdsngGrTG8p+YFxyVjq2m5GEsdyKo4e+BKhaUNPdg==", "license": "MIT", "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.12.0-next.21.tgz", - "integrity": "sha512-m5mjLjGbmiRwnv2UX48olr6NxTewt73i3f6pgqpTcQKgHxGWVvEHqDbhdhP2H8Qf31cyya/Qv9p6XQziPfjMYg==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.12.0-next.22.tgz", + "integrity": "sha512-XL6oA3ymRSQYyvg6hF1KIax6V/9vlWr5gJ8GPHVVODk1a/YfuEEY1osN5Zmo6aztUkSGKwSuac/3Ax7rfDDiSg==", "license": "MIT", "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.12.0-next.21.tgz", - "integrity": "sha512-FRGJwIPBC0UAtoWHd97bQ3OQwngp3vA4EjwZQqiicCapKoiI9BPt4+eyiZq2eq/K0+I0rHs25hw+dzU0QZL1xg==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.12.0-next.22.tgz", + "integrity": "sha512-hmkRIXxWa9P0PwfXOAO6WUw11GyV5gpxcMunqWBTkwZ4QW/hi/CkXmlLo6VHd6ceCwpUNLhCGndBtrOPrNRi4A==", "license": "MIT", "engines": { "node": ">= 20" } }, "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.12.0-next.21", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.12.0-next.21.tgz", - "integrity": "sha512-rpH/iKqn0Dvbnj+o5tv3CtDNAsA9AnBNHNmEHoJPNnB5rhR7Zw1vVg2MaE1vzCvIONQGKGkArqC+dA7ftsOcpA==", - "dev": true, + "version": "0.12.0-next.22", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.12.0-next.22.tgz", + "integrity": "sha512-X7f+7KUMm00trsXAHCHJa+x1fc3QAbk2sBctyOgpET+GLrfCXbxqrccKi7op8f0zTweAVGg1Hsc8SjjC7kwFLw==", "license": "MIT", "engines": { "node": ">= 20" @@ -1140,7 +1074,6 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-errors/-/hardhat-errors-3.0.6.tgz", "integrity": "sha512-3x+OVdZv7Rgy3z6os9pB6kiHLxs6q0PCXHRu+WLZflr44PG9zW+7V9o+ehrUqmmivlHcIFr3Qh4M2wZVuoCYww==", - "dev": true, "license": "MIT", "dependencies": { "@nomicfoundation/hardhat-utils": "^3.0.1" @@ -1292,7 +1225,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-utils/-/hardhat-utils-3.0.5.tgz", "integrity": "sha512-5zkQSuSxkwK7fQxKswJ1GGc/3AuWBSmxA7GhczTPLx28dAXQnubRU8nA48SkCkKesJq5x4TROP+XheSE2VkLUA==", - "dev": true, "license": "MIT", "dependencies": { "@streamparser/json-node": "^0.0.22", @@ -1305,12 +1237,19 @@ "undici": "^6.16.1" } }, + "node_modules/@nomicfoundation/hardhat-vendored": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-vendored/-/hardhat-vendored-3.0.0.tgz", + "integrity": "sha512-bzIOdG4iAuYSs9JSnaVOtH7qUKJ6W5+OtOiL8MlyFuLKYN2hjIisGO4pY5zR4N7xi/3RjfcnjVNz8tU0DPg2Cw==", + "license": "MIT" + }, "node_modules/@nomicfoundation/hardhat-verify": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-3.0.8.tgz", "integrity": "sha512-AkwFvx/r0AFDk0H53mReYpkw2pvi5Jq34zAyk2+cTM7o/OnOvq0xcAaidw4BQvBf9+FMeFAKjJe+zNYgrsLatg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/abi": "^5.8.0", "@nomicfoundation/hardhat-errors": "^3.0.3", @@ -1330,9 +1269,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-viem/-/hardhat-viem-3.0.1.tgz", "integrity": "sha512-sUyi3Xn31vItf925YRgHp7x6FIFfG9B+jacWYyJ0RBi7BWCrC/aSUX4jRRmpzaZ4opLQ8KXAZdxS91Yka7AYtw==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@nomicfoundation/hardhat-errors": "^3.0.0", "@nomicfoundation/hardhat-utils": "^3.0.5" @@ -1363,7 +1300,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-zod-utils/-/hardhat-zod-utils-3.0.1.tgz", "integrity": "sha512-I6/pyYiS9p2lLkzQuedr1ScMocH+ew8l233xTi+LP92gjEiviJDxselpkzgU01MUM0t6BPpfP8yMO958LDEJVg==", - "dev": true, "license": "MIT", "dependencies": { "@nomicfoundation/hardhat-errors": "^3.0.0", @@ -1416,6 +1352,107 @@ "@ethersproject/rlp": "^5.6.1" } }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/ethers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", + "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@nomicfoundation/ignition-ui": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-3.0.6.tgz", @@ -1426,7 +1463,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 12" @@ -1445,7 +1481,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1456,7 +1491,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1467,7 +1501,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1478,7 +1511,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1489,7 +1521,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1500,7 +1531,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1511,7 +1541,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1528,7 +1557,6 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "dev": true, "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" @@ -1538,7 +1566,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dev": true, "license": "MIT", "dependencies": { "@noble/curves": "~1.4.0", @@ -1553,7 +1580,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "~1.4.0", @@ -1567,7 +1593,6 @@ "version": "9.47.1", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.47.1.tgz", "integrity": "sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -1585,69 +1610,21 @@ "version": "0.0.22", "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.22.tgz", "integrity": "sha512-b6gTSBjJ8G8SuO3Gbbj+zXbVx8NSs1EbpbMKpzGLWMdkR+98McH9bEjSz3+0mPJf68c5nxa3CrJHp5EQNXM6zQ==", - "dev": true, "license": "MIT" }, "node_modules/@streamparser/json-node": { "version": "0.0.22", "resolved": "https://registry.npmjs.org/@streamparser/json-node/-/json-node-0.0.22.tgz", "integrity": "sha512-sJT2ptNRwqB1lIsQrQlCoWk5rF4tif9wDh+7yluAGijJamAhrHGYpFB/Zg3hJeceoZypi74ftXk8DHzwYpbZSg==", - "dev": true, "license": "MIT", "dependencies": { "@streamparser/json": "^0.0.22" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { - "version": "22.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", - "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", + "version": "22.19.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz", + "integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==", "dev": true, "license": "MIT", "dependencies": { @@ -1658,7 +1635,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/wevm" @@ -1676,54 +1652,19 @@ } } }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/adm-zip": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.3.0" } }, - "node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "dev": true, - "license": "MIT" - }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -1733,7 +1674,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1753,23 +1693,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, "node_modules/bn.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", @@ -1782,7 +1705,8 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/cbor2": { "version": "1.12.0", @@ -1794,21 +1718,10 @@ "node": ">=18.7" } }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -1821,7 +1734,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -1855,18 +1767,10 @@ "license": "MIT", "peer": true }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1880,16 +1784,6 @@ } } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -1901,12 +1795,25 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/elliptic": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -1922,13 +1829,13 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1", @@ -1942,7 +1849,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -1952,7 +1858,6 @@ "version": "0.27.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -1994,7 +1899,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, "license": "MIT", "dependencies": { "@noble/curves": "1.4.2", @@ -2003,112 +1907,16 @@ "@scure/bip39": "1.3.0" } }, - "node_modules/ethers": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", - "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "1.10.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "22.7.5", - "aes-js": "4.0.0-beta.5", - "tslib": "2.7.0", - "ws": "8.17.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ethers/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ethers/node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/ethers/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT" - }, - "node_modules/ethers/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true, "license": "MIT" }, "node_modules/fast-equals": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz", "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -2124,7 +1932,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -2139,7 +1946,6 @@ "version": "4.13.0", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", - "dev": true, "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -2149,15 +1955,15 @@ } }, "node_modules/hardhat": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-3.1.2.tgz", - "integrity": "sha512-ULD5dQEU2/eXh+D/bfgD7j0kV0ynFAGh+F77VNLsQ7MAMTbFEAJLchyubzzeNBTh4n2pu0CG3juECg9s9mjTuA==", - "dev": true, + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-3.1.4.tgz", + "integrity": "sha512-HHKiZqdK5/INqDqGz8JqTlTCv/vpHLM9b0gCrz9hrSALgR5mo8YJkhPl8fGDcITNkkG23ksdCH+pNUEKPJX5dw==", "license": "MIT", "dependencies": { - "@nomicfoundation/edr": "0.12.0-next.21", + "@nomicfoundation/edr": "0.12.0-next.22", "@nomicfoundation/hardhat-errors": "^3.0.6", "@nomicfoundation/hardhat-utils": "^3.0.5", + "@nomicfoundation/hardhat-vendored": "^3.0.0", "@nomicfoundation/hardhat-zod-utils": "^3.0.1", "@nomicfoundation/solidity-analyzer": "^0.1.1", "@sentry/core": "^9.4.0", @@ -2196,6 +2002,7 @@ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -2207,6 +2014,7 @@ "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -2235,7 +2043,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "dev": true, "funding": [ { "type": "github", @@ -2321,7 +2128,6 @@ "version": "3.1.6", "resolved": "https://registry.npmjs.org/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz", "integrity": "sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==", - "dev": true, "license": "MIT", "engines": { "node": ">=7.10.1" @@ -2364,18 +2170,10 @@ "dev": true, "license": "MIT" }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, "node_modules/micro-eth-signer": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz", "integrity": "sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==", - "dev": true, "license": "MIT", "dependencies": { "@noble/curves": "~1.8.1", @@ -2387,7 +2185,6 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "1.7.2" @@ -2403,7 +2200,6 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", - "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -2416,7 +2212,6 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.7.3.tgz", "integrity": "sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==", - "dev": true, "license": "MIT", "dependencies": { "@scure/base": "~1.2.5" @@ -2429,7 +2224,6 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" @@ -2440,14 +2234,16 @@ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/minimist": { "version": "1.2.8", @@ -2463,7 +2259,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/ndjson": { @@ -2487,10 +2282,9 @@ } }, "node_modules/ox": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.11.1.tgz", - "integrity": "sha512-1l1gOLAqg0S0xiN1dH5nkPna8PucrZgrIJOfS49MLNiMevxu07Iz4ZjuJS9N+xifvT+PsZyIptS7WHM8nC+0+A==", - "dev": true, + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.11.3.tgz", + "integrity": "sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw==", "funding": [ { "type": "github", @@ -2521,14 +2315,12 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", - "dev": true, "license": "MIT" }, "node_modules/ox/node_modules/@noble/ciphers": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", - "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -2541,7 +2333,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "1.8.0" @@ -2557,7 +2348,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -2570,7 +2360,6 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" @@ -2580,7 +2369,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "dev": true, "license": "MIT", "dependencies": { "@noble/curves": "~1.9.0", @@ -2595,7 +2383,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "~1.8.0", @@ -2609,7 +2396,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -2675,7 +2461,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -2689,7 +2474,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -2699,7 +2483,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -2709,7 +2492,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, "license": "MIT" }, "node_modules/safe-buffer": { @@ -2737,7 +2519,6 @@ "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -2777,7 +2558,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -2810,50 +2590,6 @@ "readable-stream": "3" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", @@ -2865,7 +2601,6 @@ "version": "4.21.0", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "~0.27.0", @@ -2896,7 +2631,7 @@ "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -2910,7 +2645,6 @@ "version": "6.23.0", "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", - "dev": true, "license": "MIT", "engines": { "node": ">=18.17" @@ -2930,18 +2664,10 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, "node_modules/viem": { - "version": "2.43.5", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.43.5.tgz", - "integrity": "sha512-QuJpuEMEPM3EreN+vX4mVY68Sci0+zDxozYfbh/WfV+SSy/Gthm74PH8XmitXdty1xY54uTCJ+/Gbbd1IiMPSA==", - "dev": true, + "version": "2.44.4", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.44.4.tgz", + "integrity": "sha512-sJDLVl2EsS5Fo7GSWZME5CXEV7QRYkUJPeBw7ac+4XI3D4ydvMw/gjulTsT5pgqcpu70BploFnOAC6DLpan1Yg==", "funding": [ { "type": "github", @@ -2956,7 +2682,7 @@ "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", - "ox": "0.11.1", + "ox": "0.11.3", "ws": "8.18.3" }, "peerDependencies": { @@ -2972,7 +2698,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "1.8.0" @@ -2988,7 +2713,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -3001,7 +2725,6 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "dev": true, "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" @@ -3011,7 +2734,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "dev": true, "license": "MIT", "dependencies": { "@noble/curves": "~1.9.0", @@ -3026,7 +2748,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "~1.8.0", @@ -3036,11 +2757,10 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/ws": { + "node_modules/viem/node_modules/ws": { "version": "8.18.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -3058,21 +2778,31 @@ } } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/etherlink-prediction/backend/package.json b/etherlink-prediction/backend/package.json new file mode 100644 index 0000000..77971ef --- /dev/null +++ b/etherlink-prediction/backend/package.json @@ -0,0 +1,19 @@ +{ + "name": "etherlink-prediction-backend", + "scripts": {}, + "type": "module", + "devDependencies": { + "@nomicfoundation/hardhat-ignition": "^3.0.6", + "@nomicfoundation/hardhat-toolbox-viem": "^5.0.1", + "@types/node": "^22.19.7", + "forge-std": "github:foundry-rs/forge-std#v1.9.4", + "hardhat": "^3.1.4", + "typescript": "~5.8.0", + "viem": "^2.44.4" + }, + "dependencies": { + "@nomicfoundation/hardhat-viem": "^3.0.1", + "@openzeppelin/contracts": "^5.4.0", + "dotenv": "^17.2.3" + } +} diff --git a/etherlink-prediction/backend/scripts/deploySandbox.js b/etherlink-prediction/backend/scripts/deploySandbox.js new file mode 100644 index 0000000..44b17ff --- /dev/null +++ b/etherlink-prediction/backend/scripts/deploySandbox.js @@ -0,0 +1,45 @@ +// scripts/deploy.js +import { network } from "hardhat"; + +async function main() { + + const { viem, networkName } = await network.connect(); + const client = await viem.getPublicClient(); + const [walletClient] = await viem.getWalletClients(); + + console.log(`Deploying contract to ${networkName}...`); + + const contract = await viem.deployContract("PredictxtzContract"); + console.log("Contract deployed to:", contract.address); + + console.log("Creating a market"); + const tx = await contract.write.createMarket([ + "Will it rain tomorrow?", + 604800, + ]); + + console.log("Waiting for the tx to confirm"); + const marketResult = await client.waitForTransactionReceipt({ hash: tx, confirmations: 1 }); + console.log("Confirmed"); + // console.log(JSON.stringify(marketResult, (_, v) => typeof v === 'bigint' ? v.toString() : v)); + + const result = await contract.read.getMarket([BigInt(0)]); + console.log("Market:", JSON.stringify(result, (_, v) => typeof v === 'bigint' ? v.toString() : v)); + + console.log(Object.keys(contract)); + + const questionCheck = await contract.read.getMostRecentMarketQuestion(); + console.log(questionCheck); + + // console.log(Object.keys(client)); + // console.log(client.account.address); + // console.log(await client.getBalance(client.account.address)); + console.log(walletClient.account.address); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error("Deployment failed:", error); + process.exit(1); + }); diff --git a/etherlink-prediction/backend/scripts/deployShadownet.js b/etherlink-prediction/backend/scripts/deployShadownet.js new file mode 100644 index 0000000..8be9208 --- /dev/null +++ b/etherlink-prediction/backend/scripts/deployShadownet.js @@ -0,0 +1,21 @@ +import { network } from "hardhat"; + +async function main() { + + const { viem, networkName } = await network.connect(); + const [walletClient] = await viem.getWalletClients(); + console.log('Deploying contract with account', walletClient.account.address); + + console.log(`Deploying contract to ${networkName}...`); + + const deployedContract = await viem.deployContract("PredictxtzContract"); + + console.log("Contract deployed to:", deployedContract.address); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error("Deployment failed:", error); + process.exit(1); + }); \ No newline at end of file diff --git a/etherlink-marketpulse/tsconfig.json b/etherlink-prediction/backend/tsconfig.json similarity index 100% rename from etherlink-marketpulse/tsconfig.json rename to etherlink-prediction/backend/tsconfig.json diff --git a/etherlink-prediction/frontend/.env.example b/etherlink-prediction/frontend/.env.example new file mode 100644 index 0000000..a0d1994 --- /dev/null +++ b/etherlink-prediction/frontend/.env.example @@ -0,0 +1,5 @@ +NEXT_PUBLIC_ETHERLINK_RPC=https://node.shadownet.etherlink.com +NEXT_PUBLIC_CONTRACT_ADDRESS=0xYourDeployedContract +NEXT_PUBLIC_CHAIN_ID=127823 +NEXT_PUBLIC_THIRDWEB_CLIENT_ID=your-thirdweb-client-id + diff --git a/etherlink-prediction/frontend/.gitignore b/etherlink-prediction/frontend/.gitignore new file mode 100644 index 0000000..44016e0 --- /dev/null +++ b/etherlink-prediction/frontend/.gitignore @@ -0,0 +1,23 @@ +# Logs +logs +*.log +npm-debug.log* + +# Dependency directories +node_modules/ +**/node_modules/ + +# Optional npm cache +.npm + +# Environment files +.env +.env.local + + +# Build directories +dist/ +build/ +# Next.js build output +.next/ +out/ \ No newline at end of file diff --git a/etherlink-prediction/frontend/README.md b/etherlink-prediction/frontend/README.md new file mode 100644 index 0000000..68e5913 --- /dev/null +++ b/etherlink-prediction/frontend/README.md @@ -0,0 +1,94 @@ + +# Etherlink Prediction Market Frontend + +A **Next.js + thirdweb SDK dApp frontend** for interacting with the [Prediction Market Smart Contract](https://github.com/onedebos/etherlink-prediction-market-contract) on [**Etherlink**](https://etherlink.com), Tezos’ Layer 2 EVM-compatible chain. + +This app provides a simple UI for: +- ✅ Placing bets on **Yes/No outcomes** in a market +- ✅ Viewing live market prices and probabilities +- ✅ Claiming winnings after a market is resolved + +## ⚡ Tech Stack + +- [Next.js](https://nextjs.org/) (React framework with SSR) +- [TypeScript](https://www.typescriptlang.org/) (type safety) +- [TailwindCSS](https://tailwindcss.com/) (styling) +- [thirdweb SDK](https://portal.thirdweb.com/) (wallet connection & contract interaction) +- Deployed on **Etherlink Shadownet** (testnet) + +## 🚀 Getting Started + +### 1. Clone the repository +```bash +git clone https://github.com/onedebos/prediction-markets-on-etherlink-demo +cd etherlink-prediction-market-frontend +```` + +### 2. Install dependencies + +```bash +npm install +``` + +### 3. Configure environment variables + +Create a `.env.local` file in the project root: + +``` +NEXT_PUBLIC_CONTRACT_ADDRESS=your_deployed_contract_address +NEXT_PUBLIC_THIRDWEB_CLIENT_ID=your_thirdweb_client_id + +``` + +* `NEXT_PUBLIC_CONTRACT_ADDRESS` → The address of your deployed prediction market contract +* `NEXT_PUBLIC_THIRDWEB_CLIENT_ID` → Your [thirdweb client ID](https://portal.thirdweb.com/dashboard) + +### 4. Run the development server + +```bash +npm run dev +``` + +Open `http://localhost:3000` in your browser. + +--- + +## 📖 Features + +* **Market List** → Browse all active prediction markets +* **Market Details** → See market description, expiration, and current odds +* **Place Bet** → Users bet on Yes/No using thirdweb’s `useContractWrite` +* **Resolve Market** → Admin resolves an event outcome +* **Claim Winnings** → Winning participants withdraw rewards + +--- + +## 🌐 Network Setup + +Connect your wallet to **Etherlink Shadownet (testnet):** + +* **Network Name**: Etherlink Shadownet +* **RPC URL**: `https://node.shadownet.etherlink.com` +* **Chain ID**: `127823` +* **Currency Symbol**: `XTZ` + +Get free testnet XTZ from the [Etherlink Faucet](https://shadownet.faucet.etherlink.com/). + +--- + +## 🛠 Development Scripts + +* `npm run dev` → Start Next.js dev server + +--- + +## 🔗 Related Repositories + +* [Prediction Market Smart Contract](https://github.com/onedebos/etherlink-prediction-market-contract) + +--- + +## ⚠️ Disclaimer + +This frontend is for **educational/demo purposes only**. +It has **not been audited** and should not be used with real funds in production. \ No newline at end of file diff --git a/etherlink-prediction/frontend/app/globals.css b/etherlink-prediction/frontend/app/globals.css new file mode 100644 index 0000000..02687bd --- /dev/null +++ b/etherlink-prediction/frontend/app/globals.css @@ -0,0 +1,123 @@ +@import 'tailwindcss'; +@import 'tw-animate-css'; + +@custom-variant dark (&:is(.dark *)); + +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.145 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.145 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: oklch(0.269 0 0); + --input: oklch(0.269 0 0); + --ring: oklch(0.439 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(0.269 0 0); + --sidebar-ring: oklch(0.439 0 0); +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/etherlink-prediction/frontend/app/layout.tsx b/etherlink-prediction/frontend/app/layout.tsx new file mode 100644 index 0000000..155a001 --- /dev/null +++ b/etherlink-prediction/frontend/app/layout.tsx @@ -0,0 +1,26 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "./globals.css"; +import { ThirdwebProvider } from "thirdweb/react"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "ExperXtz - Prediction Markets built on Etherlink.", + description: "Trade on the outcomes of future events", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + {" "} + {children} + + + ); +} diff --git a/etherlink-prediction/frontend/app/page.tsx b/etherlink-prediction/frontend/app/page.tsx new file mode 100644 index 0000000..d826040 --- /dev/null +++ b/etherlink-prediction/frontend/app/page.tsx @@ -0,0 +1,133 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { Sidebar } from "@/components/sidebar"; +import { MarketGrid } from "@/components/market-grid"; +import { + ConnectButton, + useSendAndConfirmTransaction, + useReadContract, +} from "thirdweb/react"; +import { marketIds } from "../lib/utils"; +import {client} from '../lib/providers' +import { contract } from "@/lib/contract-utils"; +import { prepareContractCall } from "thirdweb"; +import { toWei } from "thirdweb/utils"; +import toast, { Toaster } from "react-hot-toast"; + +export default function HomePage() { + const [selectedCategory, setSelectedCategory] = useState("All"); + const [existingMarketIds, setExistingMarketIds] = useState([]); + + // Fetch the number of markets from the contract + const { data: marketCounter } = useReadContract({ + contract: contract, + method: "marketCounter", + params: [], + }); + + const { mutateAsync: mutateTransaction } = useSendAndConfirmTransaction(); + + useEffect(() => { + // Update existingMarketIds when marketCounter changes + if (marketCounter) { + setExistingMarketIds(marketIds(marketCounter)); + } + }, [marketCounter]); + + // place a bet + const handlePlaceBet = async ( + marketId: number, + side: "yes" | "no", + betAmount: number + ) => { + const isYes = side === "yes" ? true : false; + const marketIdBigInt = BigInt(marketId); + const betAmountWei = toWei(betAmount.toString()); + + // Prepare and send the transaction to place a bet + const transaction = prepareContractCall({ + contract, + method: "function placeBet(uint256 marketId, bool isYes)", + params: [marketIdBigInt, isYes], + value: betAmountWei, // Attach the bet amount as value + }); + + try { + const result = await mutateTransaction(transaction); + console.log({ result }); + } catch (error) { + console.log({ error }); + toast.error("Market not active."); + } + }; + + const claimWinnings = async (marketId: number) => { + console.log("Claiming winnings for market ID:", marketId); + // Prepare and send the transaction to claim winnings + const marketIdBigInt = BigInt(marketId); + const transaction = prepareContractCall({ + contract, + method: "function claimWinnings(uint256 marketId)", + params: [marketIdBigInt], + }); + + try { + const result = await mutateTransaction(transaction); + console.log("Winnings claimed", result); + toast.success("Congrats on your winnings!"); + } catch (error) { + toast.error("Winnings have been claimed."); + } + }; + + const resolveMarket = async (marketId: number, winner: string) => { + console.log("resolve market for market ID:", marketId); + // Prepare and send the transaction to claim winnings + const marketIdBigInt = BigInt(marketId); + const winnerInt = Number(winner); + const transaction = prepareContractCall({ + contract, + method: "function resolveMarket(uint256 marketId, uint8 winner)", + params: [marketIdBigInt, winnerInt], + }); + try { + await mutateTransaction(transaction); + } catch (error) { + toast.error("Market has been resolved."); + } + }; + + return ( +
+ + +
+
+
+

Markets

+

+ Show you're an expert. Trade on the outcomes of future events. +

+
+ +
+ +
+
+ + {/* pass the array of existing market IDs to MarketGrid to generate cards for each market */} + + +
+
+ ); +} \ No newline at end of file diff --git a/etherlink-prediction/frontend/components.json b/etherlink-prediction/frontend/components.json new file mode 100644 index 0000000..335484f --- /dev/null +++ b/etherlink-prediction/frontend/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/etherlink-prediction/frontend/components/market-card.tsx b/etherlink-prediction/frontend/components/market-card.tsx new file mode 100644 index 0000000..483423d --- /dev/null +++ b/etherlink-prediction/frontend/components/market-card.tsx @@ -0,0 +1,357 @@ +import { Card } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + TrendingUp, + TrendingDown, + Clock, + DollarSign, + CheckCircle2, +} from "lucide-react"; +import { cn } from "@/lib/utils"; +import { useState, useMemo } from "react"; +import { useReadContract } from "thirdweb/react"; +import { contract } from "@/lib/contract-utils"; +import { toEther } from "thirdweb/utils"; + +interface MarketCardProps { + handlePlaceBet: ( + marketId: number, + side: "yes" | "no", + betAmount: number + ) => void; + marketId: number; +} + +export function MarketCard({ marketId, handlePlaceBet }: MarketCardProps) { + const [hoveredSide, setHoveredSide] = useState<"yes" | "no" | null>(null); + const [selectedSide, setSelectedSide] = useState<"yes" | "no" | null>(null); + const [betAmount, setBetAmount] = useState(10); + const [showBettingInterface, setShowBettingInterface] = useState(false); + + // get Data about the market from the contract + const { + data: marketInfo, + isLoading: isLoadingMarketInfo, + error: marketInfoError, + } = useReadContract({ + contract: contract, + method: "getMarket", + params: [BigInt(marketId)], + }); + + const { + data: marketProbData, + isLoading: isLoadingMarketProb, + error: marketProbError, + } = useReadContract({ + contract: contract, + method: "getProbability", + params: [BigInt(marketId), true], + }); + + // Parse the market data using useMemo for performance and consistency + const marketData = useMemo(() => { + if (!marketInfo) { + return undefined; + } + + const typedMarketInfo = marketInfo as any; + const typedMarketProbData = marketProbData as any; + + // Ensure all BigInts are handled correctly to prevent precision loss + const totalYesAmount = typedMarketInfo.totalYesAmount as bigint; + const totalNoAmount = typedMarketInfo.totalNoAmount as bigint; + const totalYesShares = typedMarketInfo.totalYesShares as bigint; + const totalNoShares = typedMarketInfo.totalNoShares as bigint; + const probYes = typedMarketProbData as bigint; + + return { + title: typedMarketInfo.question, + endTime: typedMarketInfo.endTime.toString(), + probYes: probYes.toString(), + probNo: 100 - Number(probYes), + change: Number(probYes) - (100 - Number(typedMarketProbData)), // difference between yes and no + volume: Number(toEther(totalYesAmount + totalNoAmount)), + resolved: typedMarketInfo.resolved, + totalYesShares: totalYesShares, + winner: typedMarketInfo.winner, + totalNoShares: totalNoShares, + image: "/penguin-mascot.png", + marketBalance: toEther(typedMarketInfo.marketBalance), + }; + }, [marketInfo]); + + const calculatePotentialPayout = (betAmount: number) => { + if (betAmount <= 0) return 0; + + // NOTE: The code here does not take into account other holders of a position in the pool + // in this calculation + const totalPool = marketData ? marketData.volume + betAmount : 0; + return totalPool; + }; + + const calculateProfit = (amount: number) => { + const payout = calculatePotentialPayout(amount); + + return payout - amount; + }; + + if (!isLoadingMarketInfo) { + return ( + +
+ {/* Header */} +
+
+ {marketData?.title} + + XTZ + +
+
+
+ {marketData?.probYes}% +
+ +
= 0 ? "text-green-400" : "text-red-400" + )} + > + {marketData && marketData.change >= 0 ? ( + + ) : ( + + )} + {marketData && Math.abs(marketData.change)}% +
+
+
+ + {/* Title */} +

+ {marketData?.title} +

+ + {/* Probability Bar */} +
+
+ {marketData?.probYes}% + {marketData?.probNo}% +
+
+
+
+
+ + {/* Betting Interface */} + {!showBettingInterface ? ( +
+ + +
+ ) : ( +
+ {/* Selected Side Display */} +
+ Betting on: + + {selectedSide?.toUpperCase()} + +
+ + {/* Bet Amount Slider */} +
+
+ Bet Amount: + + {betAmount} XTZ + +
+ + setBetAmount(parseInt(e.target.value))} + className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer slider" + style={{ + background: `linear-gradient(to right, ${ + selectedSide === "yes" ? "#10b981" : "#ef4444" + } 0%, ${selectedSide === "yes" ? "#10b981" : "#ef4444"} ${ + (betAmount / 1000) * 100 + }%, #374151 ${(betAmount / 1000) * 100}%, #374151 100%)`, + }} + /> + +
+ 10 XTZ + 1000 XTZ +
+
+ + {/* Real-time Returns */} +
+
+ Potential Win: + + {calculatePotentialPayout(betAmount)} XTZ + +
+
+ Profit: + 0 + ? "text-green-400" + : "text-red-400" + )} + > + {calculateProfit(betAmount).toFixed(2)} XTZ + +
+
+ Return: + + + + {((calculateProfit(betAmount) / betAmount) * 100).toFixed( + 1 + )} + % + +
+
+ + {/* Action Buttons */} +
+ + +
+
+ )} + + {/* Footer Stats */} +
+
+
+ + {marketData?.marketBalance} XTZ +
+
+ + {new Date( + parseInt(marketData?.endTime) * 1000 + ).toLocaleDateString()} +
+
+ {!marketData?.resolved ? ( + + + Active + + ) : ( + + + Resolved + + )} +
+
+ + ); + } +} \ No newline at end of file diff --git a/etherlink-prediction/frontend/components/market-grid.tsx b/etherlink-prediction/frontend/components/market-grid.tsx new file mode 100644 index 0000000..0e26b08 --- /dev/null +++ b/etherlink-prediction/frontend/components/market-grid.tsx @@ -0,0 +1,42 @@ +import { MarketCard } from "@/components/market-card"; +import ResolveMarkets from "@/components/resolve-markets"; + +interface MarketGridProps { + existingMarketIds: number[]; + handlePlaceBet: ( + marketId: number, + side: "yes" | "no", + betAmount: number + ) => void; + claimWinnings: (marketId: number) => void; + resolveMarket: (marketId: number, winner: string) => void; +} +export function MarketGrid({ + existingMarketIds, + handlePlaceBet, + claimWinnings, + resolveMarket, +}: MarketGridProps) { + return ( +
+ {existingMarketIds.map((marketId) => ( +
+ + +
+ +
+
+ ))} +
+ ); +} \ No newline at end of file diff --git a/etherlink-prediction/frontend/components/market-modal.tsx b/etherlink-prediction/frontend/components/market-modal.tsx new file mode 100644 index 0000000..c4a68b7 --- /dev/null +++ b/etherlink-prediction/frontend/components/market-modal.tsx @@ -0,0 +1,207 @@ +"use client" + +import { useState } from "react" +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Badge } from "@/components/ui/badge" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" +import { X, TrendingUp, TrendingDown, Clock, DollarSign, Users } from 'lucide-react' +import { Market } from "@/types/market" +import { cn } from "@/lib/utils" + +interface MarketModalProps { + market: Market + onClose: () => void +} + +export function MarketModal({ market, onClose }: MarketModalProps) { + const [activeTab, setActiveTab] = useState("buy") + const [selectedSide, setSelectedSide] = useState<"yes" | "no" | null>(null) + const [amount, setAmount] = useState("") + + const isPositiveChange = market.change >= 0 + + return ( + + + +
+
+ {market.title} +
+ + {market.title} + +

{market.description}

+
+
+ +
+
+ +
+ {/* Market Stats */} +
+
+
+ {market.probability}% +
+ {isPositiveChange ? ( + + ) : ( + + )} + {Math.abs(market.change)}% +
+
+

Current Probability

+
+ +
+
+ + {market.volume} +
+

24h Volume

+
+ +
+
+ + {market.endDate} +
+

Ends

+
+
+ + {/* Probability Bar */} +
+
+ YES {market.probability}% + NO {100 - market.probability}% +
+
+
+
+
+ + {/* Trading Interface */} + + + + Buy + + + Sell + + + + +
+

Pick a side

+
+ + +
+
+ + {selectedSide && ( +
+
+ + setAmount(e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+ +
+
+ Price per share + + ${selectedSide === "yes" ? market.yesPrice.toFixed(2) : market.noPrice.toFixed(2)} + +
+
+ Shares + + {amount ? (parseFloat(amount) / (selectedSide === "yes" ? market.yesPrice : market.noPrice)).toFixed(2) : "0.00"} + +
+
+ Potential return + + ${amount ? (parseFloat(amount) / (selectedSide === "yes" ? market.yesPrice : market.noPrice)).toFixed(2) : "0.00"} + +
+
+ + +
+ )} +
+ + +
+

You don't own any shares in this market

+ +
+
+
+
+ +
+ ) +} diff --git a/etherlink-prediction/frontend/components/resolve-markets.tsx b/etherlink-prediction/frontend/components/resolve-markets.tsx new file mode 100644 index 0000000..35898f9 --- /dev/null +++ b/etherlink-prediction/frontend/components/resolve-markets.tsx @@ -0,0 +1,258 @@ +import { Card } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Clock, + DollarSign, + CheckCircle2, + AlertTriangle, +} from "lucide-react"; +import { useState, useMemo } from "react"; +import { useReadContract } from "thirdweb/react"; +import { contract } from "@/lib/contract-utils"; +import { toEther } from "thirdweb/utils"; + +interface ResolveMarketsProps { + marketId: number; + claimWinnings: (marketId: number) => void; + resolveMarket: (marketId: number, winner:string) => void; +} + +export default function ResolveMarkets({ + marketId, + claimWinnings, + resolveMarket, +}: ResolveMarketsProps) { + const [selectedWinner, setSelectedWinner] = useState<"1" | "2" | "">(""); + const [isResolving, setIsResolving] = useState(false); + + // get Data about the market from the contract + const { data: marketInfo, isLoading: isLoadingMarketInfo } = useReadContract({ + contract: contract, + method: "getMarket", + params: [BigInt(marketId)], + }); + + // Parse the market data using useMemo for performance and consistency + const marketData = useMemo(() => { + if (!marketInfo) { + return undefined; + } + + const typedMarketInfo = marketInfo as any; + + // Ensure all BigInts are handled correctly to prevent precision loss + const totalYesAmount = typedMarketInfo.totalYesAmount as bigint; + const totalNoAmount = typedMarketInfo.totalNoAmount as bigint; + const totalYesShares = typedMarketInfo.totalYesShares as bigint; + const totalNoShares = typedMarketInfo.totalNoShares as bigint; + + return { + title: typedMarketInfo.question, + endTime: typedMarketInfo.endTime.toString(), + volume: Number(toEther(totalYesAmount + totalNoAmount)), + resolved: typedMarketInfo.resolved, + totalYesShares: totalYesShares, + winner: typedMarketInfo.winner, + totalNoShares: totalNoShares, + image: "/penguin-mascot.png", + marketBalance: toEther(typedMarketInfo.marketBalance) + }; + }, [marketInfo]); + + + if (isLoadingMarketInfo || !marketData) { + return ( + +
+
+
+
+
+
+
+
+ ); + } + + return ( + +
+ {/* Header */} +
+
+ {marketData.title} + + Market #{marketId} + + {marketData.resolved && ( + + + Resolved + + )} +
+
+ + {/* Title */} +

+ {marketData.title} +

+ + {/* Resolution Interface */} + {!marketData.resolved ? ( +
+
+ + + Market Resolution Required + +
+ + {/* Winner Selection */} +
+ + +
+ + {/* Preview */} + {selectedWinner && ( +
+
+ Resolution Preview: +
+
+ Market ID: + #{marketId} +
+
+ Winner: + + Side {selectedWinner} ( + {selectedWinner === "1" ? "YES" : "NO"}) + +
+
+ )} + + {/* Resolve Button */} + + + {/* Warning */} +
+
+ +
+ Warning: Market resolution is permanent and + cannot be undone. Verify the outcome before proceeding. +
+
+
+
+ ) : ( +
+
+
+ + Market Resolved +
+
+ Winning side: {marketData.winner === 1 ? "Yes" : "No"} +
+
+
+ )} + + {/* Show resolved status */} + {marketData?.resolved && ( + + )} + + {/* Footer Stats */} +
+
+
+ + {marketData.marketBalance} XTZ +
+
+ + {new Date( + parseInt(marketData.endTime) * 1000 + ).toLocaleDateString()} +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/etherlink-prediction/frontend/components/sidebar.tsx b/etherlink-prediction/frontend/components/sidebar.tsx new file mode 100644 index 0000000..005da2e --- /dev/null +++ b/etherlink-prediction/frontend/components/sidebar.tsx @@ -0,0 +1,88 @@ +import { Home, TrendingUp, Trophy, DollarSign, Newspaper, Gamepad2, Cpu, Briefcase, Users } from 'lucide-react' +import { cn } from "@/lib/utils" + +interface SidebarProps { + selectedCategory: string + onCategoryChange: (category: string) => void +} + +const navigation = [ + { name: "Home", icon: Home, href: "#" }, + { name: "Markets", icon: TrendingUp, href: "#", active: true }, + { name: "Leaderboard", icon: Trophy, href: "#" }, + { name: "Earn", icon: DollarSign, href: "#" }, + { name: "News", icon: Newspaper, href: "#" }, +] + +const topics = [ + { name: "All", icon: "🌐", markets: "All Markets" }, + { name: "Crypto", icon: "₿", markets: "27 Markets" }, + { name: "Sports", icon: "⚽", markets: "15 Markets" }, + { name: "Politics", icon: "🏛️", markets: "8 Markets" }, + { name: "Economy", icon: "📈", markets: "12 Markets" }, + { name: "Gaming", icon: "🎮", markets: "6 Markets" }, + { name: "Culture", icon: "🎭", markets: "9 Markets" }, + { name: "Tech & Science", icon: "🔬", markets: "11 Markets" }, +] + +export function Sidebar({ selectedCategory, onCategoryChange }: SidebarProps) { + return ( +
+ {/* Logo */} +
+
+
+ +
+ PredictXtz +
+
+ + {/* Navigation */} +
+ + {/* Topics */} +
+

+ Topics +

+
+ {topics.map((topic) => ( + + ))} +
+
+
+ ) +} diff --git a/etherlink-prediction/frontend/components/theme-provider.tsx b/etherlink-prediction/frontend/components/theme-provider.tsx new file mode 100644 index 0000000..55c2f6e --- /dev/null +++ b/etherlink-prediction/frontend/components/theme-provider.tsx @@ -0,0 +1,11 @@ +'use client' + +import * as React from 'react' +import { + ThemeProvider as NextThemesProvider, + type ThemeProviderProps, +} from 'next-themes' + +export function ThemeProvider({ children, ...props }: ThemeProviderProps) { + return {children} +} diff --git a/etherlink-prediction/frontend/components/trading-modal.tsx b/etherlink-prediction/frontend/components/trading-modal.tsx new file mode 100644 index 0000000..5294a98 --- /dev/null +++ b/etherlink-prediction/frontend/components/trading-modal.tsx @@ -0,0 +1,148 @@ +"use client" + +import { useState, useEffect } from "react" +import { Dialog, DialogContent } from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Slider } from "@/components/ui/slider" +import { X } from 'lucide-react' +import { Market } from "@/types/market" +import { cn } from "@/lib/utils" + +interface TradingModalProps { + market: Market + side: 'yes' | 'no' + onClose: () => void + onConfirmTrade: (market: Market, side: 'yes' | 'no', amount: number) => void +} + +export function TradingModal({ market, side, onClose, onConfirmTrade }: TradingModalProps) { + const [amount, setAmount] = useState(10) + const [sliderValue, setSliderValue] = useState([10]) + + const price = side === 'yes' ? market.yesPrice : market.noPrice + const shares = amount / price + const potentialWin = shares * 1 // Each share pays $1 if correct + const profit = potentialWin - amount + + useEffect(() => { + setAmount(sliderValue[0]) + }, [sliderValue]) + + const handleAmountChange = (newAmount: number) => { + setAmount(newAmount) + setSliderValue([newAmount]) + } + + const handleConfirm = () => { + onConfirmTrade(market, side, amount) + onClose() + } + + return ( + + +
+ {/* Header */} +
+
+ {market.title} +

+ {market.title} +

+
+ +
+ + {/* Amount Selection */} +
+
+
+
${amount}
+
+ + +
+
+ + {/* Slider */} +
+ +
+
+
+ + {/* Buy Button */} + + + {/* Trade Details */} +
+
+ Shares + {shares.toFixed(2)} +
+
+ Price per share + ${price.toFixed(2)} +
+
+ Potential profit + 0 ? "text-green-400" : "text-red-400" + )}> + ${profit.toFixed(2)} + +
+
+
+
+
+ ) +} diff --git a/etherlink-prediction/frontend/components/ui/accordion.tsx b/etherlink-prediction/frontend/components/ui/accordion.tsx new file mode 100644 index 0000000..4a8cca4 --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/accordion.tsx @@ -0,0 +1,66 @@ +"use client" + +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDownIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Accordion({ + ...props +}: React.ComponentProps) { + return +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + + ) +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ) +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/etherlink-prediction/frontend/components/ui/alert-dialog.tsx b/etherlink-prediction/frontend/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..0863e40 --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/alert-dialog.tsx @@ -0,0 +1,157 @@ +"use client" + +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +function AlertDialog({ + ...props +}: React.ComponentProps) { + return +} + +function AlertDialogTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogPortal({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + ) +} + +function AlertDialogHeader({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogFooter({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AlertDialogCancel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/etherlink-prediction/frontend/components/ui/alert.tsx b/etherlink-prediction/frontend/components/ui/alert.tsx new file mode 100644 index 0000000..1421354 --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/alert.tsx @@ -0,0 +1,66 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", + { + variants: { + variant: { + default: "bg-card text-card-foreground", + destructive: + "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ) +} + +function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDescription({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { Alert, AlertTitle, AlertDescription } diff --git a/etherlink-prediction/frontend/components/ui/aspect-ratio.tsx b/etherlink-prediction/frontend/components/ui/aspect-ratio.tsx new file mode 100644 index 0000000..3df3fd0 --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/aspect-ratio.tsx @@ -0,0 +1,11 @@ +"use client" + +import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" + +function AspectRatio({ + ...props +}: React.ComponentProps) { + return +} + +export { AspectRatio } diff --git a/etherlink-prediction/frontend/components/ui/avatar.tsx b/etherlink-prediction/frontend/components/ui/avatar.tsx new file mode 100644 index 0000000..71e428b --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/avatar.tsx @@ -0,0 +1,53 @@ +"use client" + +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "@/lib/utils" + +function Avatar({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AvatarImage({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AvatarFallback({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/etherlink-prediction/frontend/components/ui/badge.tsx b/etherlink-prediction/frontend/components/ui/badge.tsx new file mode 100644 index 0000000..0205413 --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/badge.tsx @@ -0,0 +1,46 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", + secondary: + "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", + destructive: + "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Badge({ + className, + variant, + asChild = false, + ...props +}: React.ComponentProps<"span"> & + VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : "span" + + return ( + + ) +} + +export { Badge, badgeVariants } diff --git a/etherlink-prediction/frontend/components/ui/breadcrumb.tsx b/etherlink-prediction/frontend/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..eb88f32 --- /dev/null +++ b/etherlink-prediction/frontend/components/ui/breadcrumb.tsx @@ -0,0 +1,109 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { + return