From c9c56a99d451c1abb61764089c6aa667f30922d9 Mon Sep 17 00:00:00 2001 From: Unique Divine <51418232+Unique-Divine@users.noreply.github.com> Date: Thu, 9 Jan 2025 15:55:02 -0600 Subject: [PATCH] feat(evm-oracle): add Solidity contract that we can use to expose the Nibiru Oracle in the ChainLink interface (#2149) * feat(evm-oracle): add Solidity contract that we can use to expose the Nibiru Oracle in the ChainLink interface * chore: change log * feat(evm-oracle): add decimals to the consturctor for NibiruOracleChainLinkLike * feat: make solidity available on npm (@nibiruchain/solidity) * chore: formatter and linter * (evm-contracts): add require statement for pair to constructor --- CHANGELOG.md | 4 + evm-e2e/package-lock.json | 41 +- evm-e2e/package.json | 1 + justfile | 3 + x/evm/embeds/README.md | 17 +- .../abi/ChainLinkAggregatorV3Interface.json | 113 ++++ x/evm/embeds/abi/ERC20Minter.json | 412 +++++++++++++ x/evm/embeds/abi/IFunToken.json | 243 ++++++++ x/evm/embeds/abi/INibiruEvm.json | 21 + x/evm/embeds/abi/IOracle.json | 70 +++ x/evm/embeds/abi/IWasm.json | 214 +++++++ .../embeds/abi/NibiruOracleChainLinkLike.json | 155 +++++ .../ChainLinkAggregatorV3Interface.json | 122 ++++ .../contracts/IOracle.sol/IOracle.json | 39 ++ .../NibiruOracleChainLinkLike.json | 164 +++++ x/evm/embeds/contracts/IOracle.sol | 50 +- .../contracts/NibiruOracleChainLinkLike.sol | 113 ++++ x/evm/embeds/gen-abi/main.go | 98 +++ x/evm/embeds/package-lock.json | 567 +++++++----------- x/evm/embeds/package.json | 11 + x/evm/precompile/oracle.go | 69 ++- x/evm/precompile/oracle_test.go | 35 ++ 22 files changed, 2204 insertions(+), 358 deletions(-) create mode 100644 x/evm/embeds/abi/ChainLinkAggregatorV3Interface.json create mode 100644 x/evm/embeds/abi/ERC20Minter.json create mode 100644 x/evm/embeds/abi/IFunToken.json create mode 100644 x/evm/embeds/abi/INibiruEvm.json create mode 100644 x/evm/embeds/abi/IOracle.json create mode 100644 x/evm/embeds/abi/IWasm.json create mode 100644 x/evm/embeds/abi/NibiruOracleChainLinkLike.json create mode 100644 x/evm/embeds/artifacts/contracts/IOracle.sol/ChainLinkAggregatorV3Interface.json create mode 100644 x/evm/embeds/artifacts/contracts/NibiruOracleChainLinkLike.sol/NibiruOracleChainLinkLike.json create mode 100644 x/evm/embeds/contracts/NibiruOracleChainLinkLike.sol create mode 100644 x/evm/embeds/gen-abi/main.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ee72655c..afaf10c5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#2144](https://github.com/NibiruChain/nibiru/pull/2144) - feat(token-registry): Implement strongly typed Nibiru Token Registry and generation command - [#2145](https://github.com/NibiruChain/nibiru/pull/2145) - chore(token-registry): add xNIBI Astrovault LST to registry - [#2147](https://github.com/NibiruChain/nibiru/pull/2147) - fix(simapp): manually add x/vesting Cosmos-SDK module types to the codec in simulation tests since they are expected by default +- [#2149](https://github.com/NibiruChain/nibiru/pull/2149) - feat(evm-oracle): +add Solidity contract that we can use to expose the Nibiru Oracle in the +ChainLink interface. Publish all precompiled contracts and ABIs on npm under +the `@nibiruchain/solidity` package. - [#2151](https://github.com/NibiruChain/nibiru/pull/2151) - feat(evm): randao support for evm - [#2152](https://github.com/NibiruChain/nibiru/pull/2152) - fix(precompile): consume gas for precompile calls regardless of error diff --git a/evm-e2e/package-lock.json b/evm-e2e/package-lock.json index 77f7df55d..2f0808745 100644 --- a/evm-e2e/package-lock.json +++ b/evm-e2e/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "devDependencies": { "@jest/globals": "^29.7.0", + "@nibiruchain/solidity": "^0.0.2", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^5.1.0", "@typechain/ethers-v6": "^0.5.1", @@ -2107,6 +2108,23 @@ "node": ">=12.0.0" } }, + "node_modules/@nibiruchain/solidity": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@nibiruchain/solidity/-/solidity-0.0.2.tgz", + "integrity": "sha512-ZWL4J5bdlzV6tQ8GemdKqWnFjxgvXCG5rjhsXzuh3rFDmdGNal9GOsCO2B2wFnPEctfg+XOOKZpLF8278/xiJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "^4.9.0" + } + }, + "node_modules/@nibiruchain/solidity/node_modules/@openzeppelin/contracts": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.6.tgz", + "integrity": "sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==", + "dev": true, + "license": "MIT" + }, "node_modules/@noble/curves": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", @@ -5082,10 +5100,11 @@ "peer": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -9644,10 +9663,11 @@ "peer": true }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -10461,10 +10481,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", diff --git a/evm-e2e/package.json b/evm-e2e/package.json index 149b78524..292d7b972 100644 --- a/evm-e2e/package.json +++ b/evm-e2e/package.json @@ -27,6 +27,7 @@ "typechain": "^8.3.2", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^5.1.0", + "@nibiruchain/solidity": "^0.0.2", "hardhat": "^2.22.15" }, "scripts": { diff --git a/justfile b/justfile index 175e1c5e9..8bf1c0ad6 100644 --- a/justfile +++ b/justfile @@ -39,6 +39,9 @@ gen-embeds: npx hardhat compile log_success "Compiled Solidity in $embeds_dir" + go run "gen-abi/main.go" + log_success "Saved ABI JSON files to $embeds_dir/abi for npm publishing" + alias gen-proto := proto-gen # Generate the Nibiru Token Registry files diff --git a/x/evm/embeds/README.md b/x/evm/embeds/README.md index e4cc8dad9..80cb1b30a 100644 --- a/x/evm/embeds/README.md +++ b/x/evm/embeds/README.md @@ -1,8 +1,21 @@ -# Nibiru Contract Embeds +# @nibiruchain/solidity + +Nibiru EVM solidity contracts and ABIs for Nibiru-specific precompiles and core protocol functionality. + +## Install + +```bash +yarn add @nibiruchain/solidity + +# OR npm install OR bun install +``` + +Solidity code is in "@nibiruchain/solidity/contracts/*", and +ABI JSON files are in "@nibiruchain/solidity/abi/*". ## Hacking -```shell +```bash npm install npx hardhat compile ``` diff --git a/x/evm/embeds/abi/ChainLinkAggregatorV3Interface.json b/x/evm/embeds/abi/ChainLinkAggregatorV3Interface.json new file mode 100644 index 000000000..ddc375519 --- /dev/null +++ b/x/evm/embeds/abi/ChainLinkAggregatorV3Interface.json @@ -0,0 +1,113 @@ +[ + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/x/evm/embeds/abi/ERC20Minter.json b/x/evm/embeds/abi/ERC20Minter.json new file mode 100644 index 000000000..e79d7bb1e --- /dev/null +++ b/x/evm/embeds/abi/ERC20Minter.json @@ -0,0 +1,412 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFromAuthority", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/x/evm/embeds/abi/IFunToken.json b/x/evm/embeds/abi/IFunToken.json new file mode 100644 index 000000000..2139a9b04 --- /dev/null +++ b/x/evm/embeds/abi/IFunToken.json @@ -0,0 +1,243 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "eventType", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "abciEvent", + "type": "string" + } + ], + "name": "AbciEvent", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "address", + "name": "funtoken", + "type": "address" + } + ], + "name": "balance", + "outputs": [ + { + "internalType": "uint256", + "name": "erc20Balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bankBalance", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "erc20", + "type": "address" + }, + { + "internalType": "string", + "name": "bankDenom", + "type": "string" + } + ], + "internalType": "struct IFunToken.FunToken", + "name": "token", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "ethAddr", + "type": "address" + }, + { + "internalType": "string", + "name": "bech32Addr", + "type": "string" + } + ], + "internalType": "struct IFunToken.NibiruAccount", + "name": "whoAddrs", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "string", + "name": "bankDenom", + "type": "string" + } + ], + "name": "bankBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "bankBalance", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "ethAddr", + "type": "address" + }, + { + "internalType": "string", + "name": "bech32Addr", + "type": "string" + } + ], + "internalType": "struct IFunToken.NibiruAccount", + "name": "whoAddrs", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "to", + "type": "string" + }, + { + "internalType": "string", + "name": "bankDenom", + "type": "string" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "bankMsgSend", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "erc20", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "to", + "type": "string" + } + ], + "name": "sendToBank", + "outputs": [ + { + "internalType": "uint256", + "name": "sentAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "bankDenom", + "type": "string" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "to", + "type": "string" + } + ], + "name": "sendToEvm", + "outputs": [ + { + "internalType": "uint256", + "name": "sentAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "who", + "type": "string" + } + ], + "name": "whoAmI", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "ethAddr", + "type": "address" + }, + { + "internalType": "string", + "name": "bech32Addr", + "type": "string" + } + ], + "internalType": "struct IFunToken.NibiruAccount", + "name": "whoAddrs", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/x/evm/embeds/abi/INibiruEvm.json b/x/evm/embeds/abi/INibiruEvm.json new file mode 100644 index 000000000..04b61a528 --- /dev/null +++ b/x/evm/embeds/abi/INibiruEvm.json @@ -0,0 +1,21 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "eventType", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "abciEvent", + "type": "string" + } + ], + "name": "AbciEvent", + "type": "event" + } +] \ No newline at end of file diff --git a/x/evm/embeds/abi/IOracle.json b/x/evm/embeds/abi/IOracle.json new file mode 100644 index 000000000..f81f8c679 --- /dev/null +++ b/x/evm/embeds/abi/IOracle.json @@ -0,0 +1,70 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "pair", + "type": "string" + } + ], + "name": "chainLinkLatestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "pair", + "type": "string" + } + ], + "name": "queryExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "blockTimeMs", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "blockHeight", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/x/evm/embeds/abi/IWasm.json b/x/evm/embeds/abi/IWasm.json new file mode 100644 index 000000000..7d7020d67 --- /dev/null +++ b/x/evm/embeds/abi/IWasm.json @@ -0,0 +1,214 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "string", + "name": "eventType", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "abciEvent", + "type": "string" + } + ], + "name": "AbciEvent", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "contractAddr", + "type": "string" + }, + { + "internalType": "bytes", + "name": "msgArgs", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "string", + "name": "denom", + "type": "string" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct INibiruEvm.BankCoin[]", + "name": "funds", + "type": "tuple[]" + } + ], + "name": "execute", + "outputs": [ + { + "internalType": "bytes", + "name": "response", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "string", + "name": "contractAddr", + "type": "string" + }, + { + "internalType": "bytes", + "name": "msgArgs", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "string", + "name": "denom", + "type": "string" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct INibiruEvm.BankCoin[]", + "name": "funds", + "type": "tuple[]" + } + ], + "internalType": "struct IWasm.WasmExecuteMsg[]", + "name": "executeMsgs", + "type": "tuple[]" + } + ], + "name": "executeMulti", + "outputs": [ + { + "internalType": "bytes[]", + "name": "responses", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "admin", + "type": "string" + }, + { + "internalType": "uint64", + "name": "codeID", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "msgArgs", + "type": "bytes" + }, + { + "internalType": "string", + "name": "label", + "type": "string" + }, + { + "components": [ + { + "internalType": "string", + "name": "denom", + "type": "string" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct INibiruEvm.BankCoin[]", + "name": "funds", + "type": "tuple[]" + } + ], + "name": "instantiate", + "outputs": [ + { + "internalType": "string", + "name": "contractAddr", + "type": "string" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "contractAddr", + "type": "string" + }, + { + "internalType": "bytes", + "name": "req", + "type": "bytes" + } + ], + "name": "query", + "outputs": [ + { + "internalType": "bytes", + "name": "response", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "contractAddr", + "type": "string" + }, + { + "internalType": "bytes", + "name": "key", + "type": "bytes" + } + ], + "name": "queryRaw", + "outputs": [ + { + "internalType": "bytes", + "name": "response", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/x/evm/embeds/abi/NibiruOracleChainLinkLike.json b/x/evm/embeds/abi/NibiruOracleChainLinkLike.json new file mode 100644 index 000000000..3d5f83213 --- /dev/null +++ b/x/evm/embeds/abi/NibiruOracleChainLinkLike.json @@ -0,0 +1,155 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "_pair", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_dec", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "_decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pair", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } +] \ No newline at end of file diff --git a/x/evm/embeds/artifacts/contracts/IOracle.sol/ChainLinkAggregatorV3Interface.json b/x/evm/embeds/artifacts/contracts/IOracle.sol/ChainLinkAggregatorV3Interface.json new file mode 100644 index 000000000..0be9cb13e --- /dev/null +++ b/x/evm/embeds/artifacts/contracts/IOracle.sol/ChainLinkAggregatorV3Interface.json @@ -0,0 +1,122 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ChainLinkAggregatorV3Interface", + "sourceName": "contracts/IOracle.sol", + "abi": [ + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "_roundId", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/x/evm/embeds/artifacts/contracts/IOracle.sol/IOracle.json b/x/evm/embeds/artifacts/contracts/IOracle.sol/IOracle.json index 887d9433c..1171c920c 100644 --- a/x/evm/embeds/artifacts/contracts/IOracle.sol/IOracle.json +++ b/x/evm/embeds/artifacts/contracts/IOracle.sol/IOracle.json @@ -3,6 +3,45 @@ "contractName": "IOracle", "sourceName": "contracts/IOracle.sol", "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "pair", + "type": "string" + } + ], + "name": "chainLinkLatestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/x/evm/embeds/artifacts/contracts/NibiruOracleChainLinkLike.sol/NibiruOracleChainLinkLike.json b/x/evm/embeds/artifacts/contracts/NibiruOracleChainLinkLike.sol/NibiruOracleChainLinkLike.json new file mode 100644 index 000000000..76abd7e4d --- /dev/null +++ b/x/evm/embeds/artifacts/contracts/NibiruOracleChainLinkLike.sol/NibiruOracleChainLinkLike.json @@ -0,0 +1,164 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "NibiruOracleChainLinkLike", + "sourceName": "contracts/NibiruOracleChainLinkLike.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_pair", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_dec", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "_decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint80", + "name": "", + "type": "uint80" + } + ], + "name": "getRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { + "internalType": "uint80", + "name": "roundId", + "type": "uint80" + }, + { + "internalType": "int256", + "name": "answer", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "startedAt", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "updatedAt", + "type": "uint256" + }, + { + "internalType": "uint80", + "name": "answeredInRound", + "type": "uint80" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pair", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b50604051620012c4380380620012c48339818101604052810190620000379190620002ce565b60128160ff16111562000081576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000789062000395565b60405180910390fd5b6000825111620000c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000bf9062000407565b60405180910390fd5b8160009081620000d9919062000674565b5080600160006101000a81548160ff021916908360ff16021790555050506200075b565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b62000166826200011b565b810181811067ffffffffffffffff821117156200018857620001876200012c565b5b80604052505050565b60006200019d620000fd565b9050620001ab82826200015b565b919050565b600067ffffffffffffffff821115620001ce57620001cd6200012c565b5b620001d9826200011b565b9050602081019050919050565b60005b8381101562000206578082015181840152602081019050620001e9565b60008484015250505050565b6000620002296200022384620001b0565b62000191565b90508281526020810184848401111562000248576200024762000116565b5b62000255848285620001e6565b509392505050565b600082601f83011262000275576200027462000111565b5b81516200028784826020860162000212565b91505092915050565b600060ff82169050919050565b620002a88162000290565b8114620002b457600080fd5b50565b600081519050620002c8816200029d565b92915050565b60008060408385031215620002e857620002e762000107565b5b600083015167ffffffffffffffff8111156200030957620003086200010c565b5b62000317858286016200025d565b92505060206200032a85828601620002b7565b9150509250929050565b600082825260208201905092915050565b7f446563696d616c732063616e6e6f742065786365656420313800000000000000600082015250565b60006200037d60198362000334565b91506200038a8262000345565b602082019050919050565b60006020820190508181036000830152620003b0816200036e565b9050919050565b7f5061697220737472696e672063616e6e6f7420626520656d7074790000000000600082015250565b6000620003ef601b8362000334565b9150620003fc82620003b7565b602082019050919050565b600060208201905081810360008301526200042281620003e0565b9050919050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200047c57607f821691505b60208210810362000492576200049162000434565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004fc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004bd565b620005088683620004bd565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005556200054f620005498462000520565b6200052a565b62000520565b9050919050565b6000819050919050565b620005718362000534565b6200058962000580826200055c565b848454620004ca565b825550505050565b600090565b620005a062000591565b620005ad81848462000566565b505050565b5b81811015620005d557620005c960008262000596565b600181019050620005b3565b5050565b601f8211156200062457620005ee8162000498565b620005f984620004ad565b8101602085101562000609578190505b620006216200061885620004ad565b830182620005b2565b50505b505050565b600082821c905092915050565b6000620006496000198460080262000629565b1980831691505092915050565b600062000664838362000636565b9150826002028217905092915050565b6200067f8262000429565b67ffffffffffffffff8111156200069b576200069a6200012c565b5b620006a7825462000463565b620006b4828285620005d9565b600060209050601f831160018114620006ec5760008415620006d7578287015190505b620006e3858262000656565b86555062000753565b601f198416620006fc8662000498565b60005b828110156200072657848901518255600182019150602085019450602081019050620006ff565b8683101562000746578489015162000742601f89168262000636565b8355505b6001600288020188555050505b505050505050565b610b59806200076b6000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80637284e4161161005b5780637284e416146100dc5780639a6fc8f5146100fa578063a8aa1b311461012e578063feaf968c1461014c5761007d565b8063313ce5671461008257806332424aa3146100a057806354fd4d50146100be575b600080fd5b61008a61016e565b6040516100979190610393565b60405180910390f35b6100a8610185565b6040516100b59190610393565b60405180910390f35b6100c6610198565b6040516100d391906103c7565b60405180910390f35b6100e46101a1565b6040516100f19190610472565b60405180910390f35b610114600480360381019061010f91906104db565b6101c9565b604051610125959493929190610530565b60405180910390f35b6101366101ec565b6040516101439190610472565b60405180910390f35b61015461027a565b604051610165959493929190610530565b60405180910390f35b6000600160009054906101000a900460ff16905090565b600160009054906101000a900460ff1681565b60006001905090565b606060006040516020016101b591906106f8565b604051602081830303815290604052905090565b60008060008060006101d961027a565b9450945094509450945091939590929450565b600080546101f99061062f565b80601f01602080910402602001604051908101604052809291908181526020018280546102259061062f565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b505050505081565b60008060008060008060008060008061080173ffffffffffffffffffffffffffffffffffffffff1663ece378ed60006040518263ffffffff1660e01b81526004016102c5919061079e565b60a060405180830381865afa1580156102e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610306919061082d565b9450945094509450945061031984610336565b985084898484849950995099509950995050505050509091929394565b600080600160009054906101000a900460ff16601261035591906108d7565b905080600a6103649190610a3f565b8361036f9190610ab9565b915050919050565b600060ff82169050919050565b61038d81610377565b82525050565b60006020820190506103a86000830184610384565b92915050565b6000819050919050565b6103c1816103ae565b82525050565b60006020820190506103dc60008301846103b8565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561041c578082015181840152602081019050610401565b60008484015250505050565b6000601f19601f8301169050919050565b6000610444826103e2565b61044e81856103ed565b935061045e8185602086016103fe565b61046781610428565b840191505092915050565b6000602082019050818103600083015261048c8184610439565b905092915050565b600080fd5b600069ffffffffffffffffffff82169050919050565b6104b881610499565b81146104c357600080fd5b50565b6000813590506104d5816104af565b92915050565b6000602082840312156104f1576104f0610494565b5b60006104ff848285016104c6565b91505092915050565b61051181610499565b82525050565b6000819050919050565b61052a81610517565b82525050565b600060a0820190506105456000830188610508565b6105526020830187610521565b61055f60408301866103b8565b61056c60608301856103b8565b6105796080830184610508565b9695505050505050565b600081905092915050565b7f4e6962697275204f7261636c6520436861696e4c696e6b2d6c696b652070726960008201527f6365206665656420666f72200000000000000000000000000000000000000000602082015250565b60006105ea602c83610583565b91506105f58261058e565b602c82019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061064757607f821691505b60208210810361065a57610659610600565b5b50919050565b60008190508160005260206000209050919050565b600081546106828161062f565b61068c8186610583565b945060018216600081146106a757600181146106bc576106ef565b60ff19831686528115158202860193506106ef565b6106c585610660565b60005b838110156106e7578154818901526001820191506020810190506106c8565b838801955050505b50505092915050565b6000610703826105dd565b915061070f8284610675565b915081905092915050565b600081546107278161062f565b61073181866103ed565b9450600182166000811461074c576001811461076257610795565b60ff198316865281151560200286019350610795565b61076b85610660565b60005b8381101561078d5781548189015260018201915060208101905061076e565b808801955050505b50505092915050565b600060208201905081810360008301526107b8818461071a565b905092915050565b6000815190506107cf816104af565b92915050565b6107de81610517565b81146107e957600080fd5b50565b6000815190506107fb816107d5565b92915050565b61080a816103ae565b811461081557600080fd5b50565b60008151905061082781610801565b92915050565b600080600080600060a0868803121561084957610848610494565b5b6000610857888289016107c0565b9550506020610868888289016107ec565b945050604061087988828901610818565b935050606061088a88828901610818565b925050608061089b888289016107c0565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006108e282610377565b91506108ed83610377565b9250828203905060ff811115610906576109056108a8565b5b92915050565b60008160011c9050919050565b6000808291508390505b60018511156109635780860481111561093f5761093e6108a8565b5b600185161561094e5780820291505b808102905061095c8561090c565b9450610923565b94509492505050565b60008261097c5760019050610a38565b8161098a5760009050610a38565b81600181146109a057600281146109aa576109d9565b6001915050610a38565b60ff8411156109bc576109bb6108a8565b5b8360020a9150848211156109d3576109d26108a8565b5b50610a38565b5060208310610133831016604e8410600b8410161715610a0e5782820a905083811115610a0957610a086108a8565b5b610a38565b610a1b8484846001610919565b92509050818404811115610a3257610a316108a8565b5b81810290505b9392505050565b6000610a4a826103ae565b9150610a5583610377565b9250610a827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461096c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610ac482610517565b9150610acf83610517565b925082610adf57610ade610a8a565b5b600160000383147f800000000000000000000000000000000000000000000000000000000000000083141615610b1857610b176108a8565b5b82820590509291505056fea2646970667358221220665d6835ef0fb5e6a6be054bbc231e9245801a249e34e054bb4b1b9bcfd25f7564736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80637284e4161161005b5780637284e416146100dc5780639a6fc8f5146100fa578063a8aa1b311461012e578063feaf968c1461014c5761007d565b8063313ce5671461008257806332424aa3146100a057806354fd4d50146100be575b600080fd5b61008a61016e565b6040516100979190610393565b60405180910390f35b6100a8610185565b6040516100b59190610393565b60405180910390f35b6100c6610198565b6040516100d391906103c7565b60405180910390f35b6100e46101a1565b6040516100f19190610472565b60405180910390f35b610114600480360381019061010f91906104db565b6101c9565b604051610125959493929190610530565b60405180910390f35b6101366101ec565b6040516101439190610472565b60405180910390f35b61015461027a565b604051610165959493929190610530565b60405180910390f35b6000600160009054906101000a900460ff16905090565b600160009054906101000a900460ff1681565b60006001905090565b606060006040516020016101b591906106f8565b604051602081830303815290604052905090565b60008060008060006101d961027a565b9450945094509450945091939590929450565b600080546101f99061062f565b80601f01602080910402602001604051908101604052809291908181526020018280546102259061062f565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b505050505081565b60008060008060008060008060008061080173ffffffffffffffffffffffffffffffffffffffff1663ece378ed60006040518263ffffffff1660e01b81526004016102c5919061079e565b60a060405180830381865afa1580156102e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610306919061082d565b9450945094509450945061031984610336565b985084898484849950995099509950995050505050509091929394565b600080600160009054906101000a900460ff16601261035591906108d7565b905080600a6103649190610a3f565b8361036f9190610ab9565b915050919050565b600060ff82169050919050565b61038d81610377565b82525050565b60006020820190506103a86000830184610384565b92915050565b6000819050919050565b6103c1816103ae565b82525050565b60006020820190506103dc60008301846103b8565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561041c578082015181840152602081019050610401565b60008484015250505050565b6000601f19601f8301169050919050565b6000610444826103e2565b61044e81856103ed565b935061045e8185602086016103fe565b61046781610428565b840191505092915050565b6000602082019050818103600083015261048c8184610439565b905092915050565b600080fd5b600069ffffffffffffffffffff82169050919050565b6104b881610499565b81146104c357600080fd5b50565b6000813590506104d5816104af565b92915050565b6000602082840312156104f1576104f0610494565b5b60006104ff848285016104c6565b91505092915050565b61051181610499565b82525050565b6000819050919050565b61052a81610517565b82525050565b600060a0820190506105456000830188610508565b6105526020830187610521565b61055f60408301866103b8565b61056c60608301856103b8565b6105796080830184610508565b9695505050505050565b600081905092915050565b7f4e6962697275204f7261636c6520436861696e4c696e6b2d6c696b652070726960008201527f6365206665656420666f72200000000000000000000000000000000000000000602082015250565b60006105ea602c83610583565b91506105f58261058e565b602c82019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061064757607f821691505b60208210810361065a57610659610600565b5b50919050565b60008190508160005260206000209050919050565b600081546106828161062f565b61068c8186610583565b945060018216600081146106a757600181146106bc576106ef565b60ff19831686528115158202860193506106ef565b6106c585610660565b60005b838110156106e7578154818901526001820191506020810190506106c8565b838801955050505b50505092915050565b6000610703826105dd565b915061070f8284610675565b915081905092915050565b600081546107278161062f565b61073181866103ed565b9450600182166000811461074c576001811461076257610795565b60ff198316865281151560200286019350610795565b61076b85610660565b60005b8381101561078d5781548189015260018201915060208101905061076e565b808801955050505b50505092915050565b600060208201905081810360008301526107b8818461071a565b905092915050565b6000815190506107cf816104af565b92915050565b6107de81610517565b81146107e957600080fd5b50565b6000815190506107fb816107d5565b92915050565b61080a816103ae565b811461081557600080fd5b50565b60008151905061082781610801565b92915050565b600080600080600060a0868803121561084957610848610494565b5b6000610857888289016107c0565b9550506020610868888289016107ec565b945050604061087988828901610818565b935050606061088a88828901610818565b925050608061089b888289016107c0565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006108e282610377565b91506108ed83610377565b9250828203905060ff811115610906576109056108a8565b5b92915050565b60008160011c9050919050565b6000808291508390505b60018511156109635780860481111561093f5761093e6108a8565b5b600185161561094e5780820291505b808102905061095c8561090c565b9450610923565b94509492505050565b60008261097c5760019050610a38565b8161098a5760009050610a38565b81600181146109a057600281146109aa576109d9565b6001915050610a38565b60ff8411156109bc576109bb6108a8565b5b8360020a9150848211156109d3576109d26108a8565b5b50610a38565b5060208310610133831016604e8410600b8410161715610a0e5782820a905083811115610a0957610a086108a8565b5b610a38565b610a1b8484846001610919565b92509050818404811115610a3257610a316108a8565b5b81810290505b9392505050565b6000610a4a826103ae565b9150610a5583610377565b9250610a827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461096c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000610ac482610517565b9150610acf83610517565b925082610adf57610ade610a8a565b5b600160000383147f800000000000000000000000000000000000000000000000000000000000000083141615610b1857610b176108a8565b5b82820590509291505056fea2646970667358221220665d6835ef0fb5e6a6be054bbc231e9245801a249e34e054bb4b1b9bcfd25f7564736f6c63430008180033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/x/evm/embeds/contracts/IOracle.sol b/x/evm/embeds/contracts/IOracle.sol index 393584f6f..a4ed075e2 100644 --- a/x/evm/embeds/contracts/IOracle.sol +++ b/x/evm/embeds/contracts/IOracle.sol @@ -17,8 +17,56 @@ interface IOracle { external view returns (uint256 price, uint64 blockTimeMs, uint64 blockHeight); + + function chainLinkLatestRoundData( + string memory pair + ) + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); } address constant ORACLE_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000801; -IOracle constant ORACLE_GATEWAY = IOracle(ORACLE_PRECOMPILE_ADDRESS); +IOracle constant NIBIRU_ORACLE = IOracle(ORACLE_PRECOMPILE_ADDRESS); + +// ChainLink interface from: +// import "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; +// solhint-disable-next-line interface-starts-with-i +interface ChainLinkAggregatorV3Interface { + function decimals() external view returns (uint8); + + function description() external view returns (string memory); + + function version() external view returns (uint256); + + function getRoundData( + uint80 _roundId + ) + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); + + function latestRoundData() + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ); +} diff --git a/x/evm/embeds/contracts/NibiruOracleChainLinkLike.sol b/x/evm/embeds/contracts/NibiruOracleChainLinkLike.sol new file mode 100644 index 000000000..e723d7b6b --- /dev/null +++ b/x/evm/embeds/contracts/NibiruOracleChainLinkLike.sol @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.19; + +import "./IOracle.sol"; + +/// @title NibiruOracleChainLinkLike +/// @notice This contract serves as a ChainLink-like data feed that sources its +/// "answer" value from the Nibiru Oracle system. The Nibiru Oracle gives price +/// data with 18 decimals universally, and that 18-decimal answer is scaled to +/// have the number of decimals specified by "decimals()". This is set at the +/// time of deployment. +/// _ _ _____ ____ _____ _____ _ _ +/// | \ | ||_ _|| _ \|_ _|| __ \ | | | | +/// | \| | | | | |_) | | | | |__) || | | | +/// | . ` | | | | _ < | | | _ / | | | | +/// | |\ | _| |_ | |_) |_| |_ | | \ \ | |__| | +/// |_| \_||_____||____/|_____||_| \_\ \____/ +/// +contract NibiruOracleChainLinkLike is ChainLinkAggregatorV3Interface { + string public pair; + uint8 public _decimals; + + constructor(string memory _pair, uint8 _dec) { + require(_dec <= 18, "Decimals cannot exceed 18"); + require(bytes(_pair).length > 0, "Pair string cannot be empty"); + pair = _pair; + _decimals = _dec; + } + + function decimals() external view override returns (uint8) { + return _decimals; + } + + /// @notice Returns a human-readable description of the oracle and its data + /// feed identifier (pair) in the Nibiru Oracle system + function description() external view override returns (string memory) { + return + string.concat("Nibiru Oracle ChainLink-like price feed for ", pair); + } + + /// @notice Oracle version number. Hardcoded to 1. + function version() external pure override returns (uint256) { + return 1; + } + + /// @notice Returns the latest data from the Nibiru Oracle. + /// @return roundId The block number when the answer was published onchain. + /// @return answer Data feed result scaled to the precision specified by + /// "decimals()" + /// @return startedAt UNIX timestamp in seconds when "answer" was published. + /// @return updatedAt UNIX timestamp in seconds when "answer" was published. + /// @return answeredInRound The ID of the round where the answer was computed. + /// Since the Nibiru Oracle does not have ChainLink's system of voting + /// rounds, this argument is a meaningless, arbitrary constant. + function latestRoundData() + public + view + override + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + ( + uint80 _roundId, + int256 answer18Dec, + uint256 _startedAt, + uint256 _updatedAt, + uint80 _answeredInRound + ) = NIBIRU_ORACLE.chainLinkLatestRoundData(pair); + answer = scaleAnswerToDecimals(answer18Dec); + return (_roundId, answer, _startedAt, _updatedAt, _answeredInRound); + } + + /// @notice Returns the latest data from the Nibiru Oracle. Historical round + /// retrieval is not supported. This method is a duplicate of + /// "latestRoundData". + /// @return roundId The block number when the answer was published onchain. + /// @return answer Data feed result scaled to the precision specified by + /// "decimals()" + /// @return startedAt UNIX timestamp in seconds when "answer" was published. + /// @return updatedAt UNIX timestamp in seconds when "answer" was published. + /// @return answeredInRound The ID of the round where the answer was computed. + /// Since the Nibiru Oracle does not have ChainLink's system of voting + /// rounds, this argument is a meaningless, arbitrary constant. + function getRoundData( + uint80 + ) + external + view + returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) + { + return latestRoundData(); + } + + function scaleAnswerToDecimals( + int256 answer18Dec + ) internal view returns (int256 answer) { + // Default answers are in 18 decimals. + // Scale down to the decimals specified in the constructor. + uint8 pow10 = 18 - _decimals; + return answer18Dec / int256(10 ** pow10); + } +} diff --git a/x/evm/embeds/gen-abi/main.go b/x/evm/embeds/gen-abi/main.go new file mode 100644 index 000000000..cefd8d2ea --- /dev/null +++ b/x/evm/embeds/gen-abi/main.go @@ -0,0 +1,98 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/fs" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "strings" +) + +// findRootPath returns the absolute path of the repository root +// This is retrievable with: go list -m -f {{.Dir}} +func findRootPath() (string, error) { + // rootPath, _ := exec.Command("go list -m -f {{.Dir}}").Output() + // This returns the path to the root of the project. + rootPathBz, err := exec.Command("go", "list", "-m", "-f", "{{.Dir}}").Output() + if err != nil { + return "", err + } + rootPath := strings.Trim(string(rootPathBz), "\n") + return rootPath, nil +} + +func main() { + // Define the input and output directories + rootPath, err := findRootPath() + if err != nil { + log.Fatalf("Unable to find repo root path: %s", err) + } + inputDir := path.Join(rootPath, "x/evm/embeds/artifacts/contracts/") + outputDir := path.Join(rootPath, "x/evm/embeds/abi/") + + // Ensure the output directory exists + err = os.MkdirAll(outputDir, os.ModePerm) + if err != nil { + log.Fatalf("Failed to create output directory: %v", err) + } + + // Walk through the input directory + err = filepath.Walk(inputDir, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + + // Process only... + if !info.IsDir() && + filepath.Ext(path) == ".json" && // .json files that + !strings.Contains(path, ".dbg") && // are NOT "dbg" files + !strings.HasPrefix(info.Name(), "Test") { // are NOT for tests + // Read the JSON file + data, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read file %s: %v", path, err) + } + + // Parse the JSON file + var parsed map[string]interface{} + err = json.Unmarshal(data, &parsed) + if err != nil { + return fmt.Errorf("failed to parse JSON in file %s: %v", path, err) + } + + // Extract the "abi" field + abi, ok := parsed["abi"] + if !ok { + fmt.Printf("No 'abi' field found in file %s, skipping...\n", path) + return nil + } + + // Marshal the ABI field back to JSON + abiData, err := json.MarshalIndent(abi, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal 'abi' field from file %s: %v", path, err) + } + + // Create the output file name + outputFileName := strings.TrimSuffix(info.Name(), filepath.Ext(info.Name())) + ".json" + outputPath := filepath.Join(outputDir, outputFileName) + + // Write the ABI JSON to the output directory + err = os.WriteFile(outputPath, abiData, 0o644) + if err != nil { + return fmt.Errorf("failed to write ABI to file %s: %v", outputPath, err) + } + + fmt.Printf("Processed and saved ABI: %s\n", outputPath) + } + + return nil + }) + if err != nil { + log.Fatalf("Error processing files: %v", err) + } +} diff --git a/x/evm/embeds/package-lock.json b/x/evm/embeds/package-lock.json index 2a45a96b1..149b1ef1b 100644 --- a/x/evm/embeds/package-lock.json +++ b/x/evm/embeds/package-lock.json @@ -1,9 +1,13 @@ { - "name": "embeds", + "name": "@nibiruchain/solidity", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { + "name": "@nibiruchain/solidity", + "version": "0.0.1", + "license": "MIT", "dependencies": { "@openzeppelin/contracts": "^4.9.0" }, @@ -1055,28 +1059,28 @@ } }, "node_modules/@nomicfoundation/edr": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.5.0.tgz", - "integrity": "sha512-nAUyjGhxntXje/1AkDX9POfH+pqUxdi4XHzIhaf/dJYs7fgAFxL3STBK1OYcA3LR7vtiylLHMz7wxjqLzlLGKg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.6.5.tgz", + "integrity": "sha512-tAqMslLP+/2b2sZP4qe9AuGxG3OkQ5gGgHE4isUuq6dUVjwCRPFhAOhpdFl+OjY5P3yEv3hmq9HjUGRa2VNjng==", "dev": true, "license": "MIT", "dependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.5.0", - "@nomicfoundation/edr-darwin-x64": "0.5.0", - "@nomicfoundation/edr-linux-arm64-gnu": "0.5.0", - "@nomicfoundation/edr-linux-arm64-musl": "0.5.0", - "@nomicfoundation/edr-linux-x64-gnu": "0.5.0", - "@nomicfoundation/edr-linux-x64-musl": "0.5.0", - "@nomicfoundation/edr-win32-x64-msvc": "0.5.0" + "@nomicfoundation/edr-darwin-arm64": "0.6.5", + "@nomicfoundation/edr-darwin-x64": "0.6.5", + "@nomicfoundation/edr-linux-arm64-gnu": "0.6.5", + "@nomicfoundation/edr-linux-arm64-musl": "0.6.5", + "@nomicfoundation/edr-linux-x64-gnu": "0.6.5", + "@nomicfoundation/edr-linux-x64-musl": "0.6.5", + "@nomicfoundation/edr-win32-x64-msvc": "0.6.5" }, "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.5.0.tgz", - "integrity": "sha512-G6OX/PESdfU4ZOyJ4MDh4eevW0wt2mduuxA+thXtTcStOiQTtPuV205h4kLOR5wRB1Zz6Zy0LedTMax7TzOtGw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.5.tgz", + "integrity": "sha512-A9zCCbbNxBpLgjS1kEJSpqxIvGGAX4cYbpDYCU2f3jVqOwaZ/NU761y1SvuCRVpOwhoCXqByN9b7HPpHi0L4hw==", "dev": true, "license": "MIT", "engines": { @@ -1084,9 +1088,9 @@ } }, "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.5.0.tgz", - "integrity": "sha512-fI7uHfHqPtdPZjkFUTpotc/F5gGv41ws+jSZy9+2AR9RDMOAIXMEArOx9rGLBcevWu8SFnyH/l/77kG/5FXbDw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.5.tgz", + "integrity": "sha512-x3zBY/v3R0modR5CzlL6qMfFMdgwd6oHrWpTkuuXnPFOX8SU31qq87/230f4szM+ukGK8Hi+mNq7Ro2VF4Fj+w==", "dev": true, "license": "MIT", "engines": { @@ -1094,9 +1098,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.5.0.tgz", - "integrity": "sha512-eMC3sWPkBZILg2/YB4Xv6IR0nggCLt5hS8K8jjHeGEeUs9pf8poBF2Oy+G4lSu0YLLjexGzHypz9/P+pIuxZHw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.5.tgz", + "integrity": "sha512-HGpB8f1h8ogqPHTyUpyPRKZxUk2lu061g97dOQ/W4CxevI0s/qiw5DB3U3smLvSnBHKOzYS1jkxlMeGN01ky7A==", "dev": true, "license": "MIT", "engines": { @@ -1104,9 +1108,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.5.0.tgz", - "integrity": "sha512-yPK0tKjYRxe5ktggFr8aBHH0DCI9uafuaD8QuzyrQAfSf/m/ebTdgthROdbYp6eRk5mJyfAQT/45fM3tnlYsWw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.5.tgz", + "integrity": "sha512-ESvJM5Y9XC03fZg9KaQg3Hl+mbx7dsSkTIAndoJS7X2SyakpL9KZpOSYrDk135o8s9P9lYJdPOyiq+Sh+XoCbQ==", "dev": true, "license": "MIT", "engines": { @@ -1114,9 +1118,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.5.0.tgz", - "integrity": "sha512-Hds8CRYi4DEyuErjcwUNSvNpMzmOYUihW4qYCoKgSBUVS5saX1PyPYvFYuYpeU5J8/T2iMk6yAPVLCxtKbgnKg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.5.tgz", + "integrity": "sha512-HCM1usyAR1Ew6RYf5AkMYGvHBy64cPA5NMbaeY72r0mpKaH3txiMyydcHibByOGdQ8iFLWpyUdpl1egotw+Tgg==", "dev": true, "license": "MIT", "engines": { @@ -1124,9 +1128,9 @@ } }, "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.5.0.tgz", - "integrity": "sha512-1hXMDSzdyh5ojwO3ZSRbt7t5KKYycGUlFdC3lgJRZ7gStB8xjb7RA3hZn2csn9OydS950Ne4nh+puNq91iXApw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.5.tgz", + "integrity": "sha512-nB2uFRyczhAvWUH7NjCsIO6rHnQrof3xcCe6Mpmnzfl2PYcGyxN7iO4ZMmRcQS7R1Y670VH6+8ZBiRn8k43m7A==", "dev": true, "license": "MIT", "engines": { @@ -1134,9 +1138,9 @@ } }, "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.5.0.tgz", - "integrity": "sha512-CFagD423400xXkRmACIR13FoocN48qi4ogRnuFQIvBDtEE3aMEajfFj4bycmQQDqnqChsZy/jwD4OxbX6oaNJw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.5.tgz", + "integrity": "sha512-B9QD/4DSSCFtWicO8A3BrsnitO1FPv7axB62wq5Q+qeJ50yJlTmyeGY3cw62gWItdvy2mh3fRM6L1LpnHiB77A==", "dev": true, "license": "MIT", "engines": { @@ -1213,9 +1217,9 @@ } }, "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.7.tgz", - "integrity": "sha512-RQfsiTwdf0SP+DtuNYvm4921X6VirCQq0Xyh+mnuGlTwEFSPZ/o27oQC+l+3Y/l48DDU7+ZcYBR+Fp+Rp94LfQ==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.8.tgz", + "integrity": "sha512-Z5PiCXH4xhNLASROlSUOADfhfpfhYO6D7Hn9xp8PddmHey0jq704cr6kfU8TRrQ4PUZbpfsZadPj+pCfZdjPIg==", "dev": true, "license": "MIT", "peer": true, @@ -1233,9 +1237,9 @@ } }, "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz", - "integrity": "sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.8.tgz", + "integrity": "sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA==", "dev": true, "license": "MIT", "peer": true, @@ -1249,18 +1253,19 @@ } }, "node_modules/@nomicfoundation/hardhat-ignition": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.5.tgz", - "integrity": "sha512-Y5nhFXFqt4owA6Ooag8ZBFDF2RAZElMXViknVIsi3m45pbQimS50ti6FU8HxfRkDnBARa40CIn7UGV0hrelzDw==", + "version": "0.15.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.9.tgz", + "integrity": "sha512-lSWqhaDOBt6gsqMadkRLvH6HdoFV1v8/bx7z+12cghaOloVwwn48CPoTH2iXXnkqilPGw8rdH5eVTE6UM+2v6Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@nomicfoundation/ignition-core": "^0.15.5", - "@nomicfoundation/ignition-ui": "^0.15.5", + "@nomicfoundation/ignition-core": "^0.15.9", + "@nomicfoundation/ignition-ui": "^0.15.9", "chalk": "^4.0.0", "debug": "^4.3.2", "fs-extra": "^10.0.0", + "json5": "^2.2.3", "prompts": "^2.4.2" }, "peerDependencies": { @@ -1269,24 +1274,24 @@ } }, "node_modules/@nomicfoundation/hardhat-ignition-ethers": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.5.tgz", - "integrity": "sha512-W6s1QN9CFxzSVZS6w9Jcj3WLaK32z2FP5MxNU2OKY1Fn9ZzLr+miXbUbWYuRHl6dxrrl6sE8cv33Cybv19pmCg==", + "version": "0.15.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.9.tgz", + "integrity": "sha512-9PwwgLv3z2ec3B26mK0IjiFezHFFBcBcs1qKaRu8SanARE4b7RvrfiLIy8ZXE7HaxgPt32kSsQzehhzAwAIj1Q==", "dev": true, "license": "MIT", "peer": true, "peerDependencies": { "@nomicfoundation/hardhat-ethers": "^3.0.4", - "@nomicfoundation/hardhat-ignition": "^0.15.5", - "@nomicfoundation/ignition-core": "^0.15.5", + "@nomicfoundation/hardhat-ignition": "^0.15.9", + "@nomicfoundation/ignition-core": "^0.15.9", "ethers": "^6.7.0", "hardhat": "^2.18.0" } }, "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.11.tgz", - "integrity": "sha512-uGPL7QSKvxrHRU69dx8jzoBvuztlLCtyFsbgfXIwIjnO3dqZRz2GNMHJoO3C3dIiUNM6jdNF4AUnoQKDscdYrA==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.12.tgz", + "integrity": "sha512-xTNQNI/9xkHvjmCJnJOTyqDSl8uq1rKb2WOVmixQxFtRd7Oa3ecO8zM0cyC2YmOK+jHB9WPZ+F/ijkHg1CoORA==", "dev": true, "license": "MIT", "peer": true, @@ -1325,9 +1330,9 @@ } }, "node_modules/@nomicfoundation/hardhat-verify": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.9.tgz", - "integrity": "sha512-7kD8hu1+zlnX87gC+UN4S0HTKBnIsDfXZ/pproq1gYsK94hgCk+exvzXbwR0X2giiY/RZPkqY9oKRi0Uev91hQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.12.tgz", + "integrity": "sha512-Lg3Nu7DCXASQRVI/YysjuAX2z8jwOCbS0w5tz2HalWGSTZThqA0v9N0v0psHbKNqzPJa8bNOeapIVSziyJTnAg==", "dev": true, "license": "MIT", "peer": true, @@ -1335,106 +1340,21 @@ "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^8.1.0", - "chalk": "^2.4.2", "debug": "^4.1.1", "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.1.0", "semver": "^6.3.0", "table": "^6.8.0", "undici": "^5.14.0" }, "peerDependencies": { - "hardhat": "^2.22.72.0.4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomicfoundation/hardhat-verify/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "hardhat": "^2.0.4" } }, "node_modules/@nomicfoundation/ignition-core": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.5.tgz", - "integrity": "sha512-FgvuoIXhakRSP524JzNQ4BviyzBBKpsFaOWubPZ4XACLT4/7vGqlJ/7DIn0D2NL2anQ2qs98/BNBY9WccXUX1Q==", + "version": "0.15.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.9.tgz", + "integrity": "sha512-X8W+7UP/UQPorpHUnGvA1OdsEr/edGi8tDpNwEqzaLm83FMZVbRWdOsr3vNICHN2XMzNY/xIm18Cx7xGKL2PQw==", "dev": true, "license": "MIT", "peer": true, @@ -1490,9 +1410,9 @@ } }, "node_modules/@nomicfoundation/ignition-ui": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.5.tgz", - "integrity": "sha512-ZcE4rIn10qKahR4OqS8rl8NM2Fbg2QYiBXgMgj74ZI0++LlCcZgB5HyaBbX+lsnKHjTXtjYD3b+2mtg7jFbAMQ==", + "version": "0.15.9", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.9.tgz", + "integrity": "sha512-8lzbT7gpJ5PoowPQDQilkwdyqBviUKDMoHp/5rhgnwG1bDslnCS+Lxuo6s9R2akWu9LtEL14dNyqQb6WsURTag==", "dev": true, "peer": true }, @@ -2568,6 +2488,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3178,7 +3099,8 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/concat-stream": { "version": "1.6.2", @@ -4035,16 +3957,20 @@ } }, "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { @@ -4318,6 +4244,7 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4453,15 +4380,15 @@ } }, "node_modules/hardhat": { - "version": "2.22.7", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.7.tgz", - "integrity": "sha512-nrXQAl+qUr75TsCLDo8P41YXLc+5U7qQMMCIrbbmy1/uQaVPncdjDrD5BR0CENvHRj7EBqO+JkofpozXoIfJKg==", + "version": "2.22.17", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.17.tgz", + "integrity": "sha512-tDlI475ccz4d/dajnADUTRc1OJ3H8fpP9sWhXhBPpYsQOg8JHq5xrDimo53UhWPl7KJmAeDCm1bFG74xvpGRpg==", "dev": true, "license": "MIT", "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.5.0", + "@nomicfoundation/edr": "^0.6.5", "@nomicfoundation/ethereumjs-common": "4.0.4", "@nomicfoundation/ethereumjs-tx": "5.0.4", "@nomicfoundation/ethereumjs-util": "9.0.4", @@ -4473,31 +4400,32 @@ "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", "boxen": "^5.1.2", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", + "chokidar": "^4.0.0", "ci-info": "^2.0.0", "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", "ethereum-cryptography": "^1.0.3", "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", + "find-up": "^5.0.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", + "json-stream-stringify": "^3.1.4", "keccak": "^3.0.2", "lodash": "^4.17.11", "mnemonist": "^0.38.0", "mocha": "^10.0.0", "p-map": "^4.0.0", + "picocolors": "^1.1.0", "raw-body": "^2.4.1", "resolve": "1.17.0", "semver": "^6.3.0", "solc": "0.8.26", "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", + "tinyglobby": "^0.2.6", "tsort": "0.0.1", "undici": "^5.14.0", "uuid": "^8.3.2", @@ -4583,59 +4511,20 @@ "@scure/base": "~1.1.0" } }, - "node_modules/hardhat/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/hardhat/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "node": ">= 14.16.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hardhat/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/hardhat/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/hardhat/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/hardhat/node_modules/ethereum-cryptography": { @@ -4666,16 +4555,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/hardhat/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/hardhat/node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -4686,17 +4565,18 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/hardhat/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/hardhat/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "dev": true, "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/hardhat/node_modules/universalify": { @@ -5155,6 +5035,16 @@ "license": "MIT", "peer": true }, + "node_modules/json-stream-stringify": { + "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" + } + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -5163,6 +5053,20 @@ "license": "ISC", "peer": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -5242,17 +5146,19 @@ } }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -5386,9 +5292,9 @@ "peer": true }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "peer": true, @@ -5445,6 +5351,7 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5533,23 +5440,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -5571,22 +5461,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -5607,48 +5481,6 @@ "dev": true, "license": "MIT" }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5870,29 +5702,35 @@ } }, "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -5911,16 +5749,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", @@ -5929,13 +5757,13 @@ "peer": true }, "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { @@ -5944,6 +5772,7 @@ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -5994,6 +5823,13 @@ "node": ">=0.12" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -6529,10 +6365,11 @@ "dev": true }, "node_modules/secp256k1/node_modules/elliptic": { - "version": "6.5.7", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", - "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "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", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -6741,15 +6578,15 @@ } }, "node_modules/solidity-coverage": { - "version": "0.8.12", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", - "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.14.tgz", + "integrity": "sha512-ItAAObe5GaEOp20kXC2BZRnph+9P7Rtoqg2mQc2SXGEHgSDF2wWd1Wxz3ntzQWXkbCtIIGdJT918HG00cObwbA==", "dev": true, "license": "ISC", "peer": true, "dependencies": { "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.18.0", + "@solidity-parser/parser": "^0.19.0", "chalk": "^2.4.2", "death": "^1.1.0", "difflib": "^0.2.4", @@ -6776,9 +6613,9 @@ } }, "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", - "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.19.0.tgz", + "integrity": "sha512-RV16k/qIxW/wWc+mLzV3ARyKUaMUTBy9tOLMzFhtNSKYeTAanQ3a5MudJKf/8arIFnA2L27SNjarQKmFg0w/jA==", "dev": true, "license": "MIT", "peer": true @@ -7236,6 +7073,48 @@ "readable-stream": "3" } }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/x/evm/embeds/package.json b/x/evm/embeds/package.json index 3f0a14b72..50174e8ff 100644 --- a/x/evm/embeds/package.json +++ b/x/evm/embeds/package.json @@ -1,4 +1,15 @@ { + "name": "@nibiruchain/solidity", + "description": "Nibiru EVM solidity contracts and ABIs for Nibiru-specific precompiles and core protocol functionality", + "version": "0.0.2", + "private": false, + "files": [ + "/contracts/**/*.sol", + "/abi", + "!/contracts/**/Test*.sol" + ], + "keywords": ["solidity", "ethereum", "smart", "contracts", "evm", "nibiru", "blockchain"], + "license": "MIT", "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^5.0.0", "bun": "^1.1.30", diff --git a/x/evm/precompile/oracle.go b/x/evm/precompile/oracle.go index b7d4cf4ad..12f559515 100644 --- a/x/evm/precompile/oracle.go +++ b/x/evm/precompile/oracle.go @@ -2,6 +2,7 @@ package precompile import ( "fmt" + "math/big" sdk "github.com/cosmos/cosmos-sdk/types" gethabi "github.com/ethereum/go-ethereum/accounts/abi" @@ -32,7 +33,8 @@ func (p precompileOracle) ABI() *gethabi.ABI { } const ( - OracleMethod_queryExchangeRate PrecompileMethod = "queryExchangeRate" + OracleMethod_queryExchangeRate PrecompileMethod = "queryExchangeRate" + OracleMethod_chainLinkLatestRoundData PrecompileMethod = "chainLinkLatestRoundData" ) // Run runs the precompiled contract @@ -51,6 +53,10 @@ func (p precompileOracle) Run( switch PrecompileMethod(method.Name) { case OracleMethod_queryExchangeRate: bz, err = p.queryExchangeRate(ctx, method, args) + // For "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol" + case OracleMethod_chainLinkLatestRoundData: + bz, err = p.chainLinkLatestRoundData(ctx, method, args) + default: // Note that this code path should be impossible to reach since // "[decomposeInput]" parses methods directly from the ABI. @@ -75,6 +81,16 @@ type precompileOracle struct { oracleKeeper oraclekeeper.Keeper } +// Implements "IOracle.queryExchangeRate" +// +// ```solidity +// function queryExchangeRate( +// string memory pair +// ) +// external +// view +// returns (uint256 price, uint64 blockTimeMs, uint64 blockHeight); +// ``` func (p precompileOracle) queryExchangeRate( ctx sdk.Context, method *gethabi.Method, @@ -118,3 +134,54 @@ func (p precompileOracle) parseQueryExchangeRateArgs(args []any) ( return pair, nil } + +// Implements "IOracle.chainLinkLatestRoundData" +// +// ```solidity +// interface IOracle { +// function chainLinkLatestRoundData( +// string memory pair +// ) +// external +// view +// returns ( +// uint80 roundId, +// int256 answer, +// uint256 startedAt, +// uint256 updatedAt, +// uint80 answeredInRound +// ); +// // ... +// } +// ``` +func (p precompileOracle) chainLinkLatestRoundData( + ctx sdk.Context, + method *gethabi.Method, + args []any, +) (bz []byte, err error) { + pair, err := p.parseQueryExchangeRateArgs(args) + if err != nil { + return nil, err + } + assetPair, err := asset.TryNewPair(pair) + if err != nil { + return nil, err + } + + priceAtBlock, err := p.oracleKeeper.ExchangeRates.Get(ctx, assetPair) + if err != nil { + return nil, err + } + + roundId := new(big.Int).SetUint64(priceAtBlock.CreatedBlock) + answer := priceAtBlock.ExchangeRate.BigInt() // 18 decimals + timestampSeconds := big.NewInt(priceAtBlock.BlockTimestampMs / 1000) + answeredInRound := big.NewInt(420) // for no reason in particular / unused + return method.Outputs.Pack( + roundId, + answer, + timestampSeconds, // startedAt (seconds) + timestampSeconds, // updatedAt (seconds) + answeredInRound, + ) +} diff --git a/x/evm/precompile/oracle_test.go b/x/evm/precompile/oracle_test.go index 6fad8af7f..6c738ee90 100644 --- a/x/evm/precompile/oracle_test.go +++ b/x/evm/precompile/oracle_test.go @@ -114,6 +114,41 @@ func (s *OracleSuite) TestOracle_HappyPath() { s.Equal(fmt.Sprintf("%d", out[1].(uint64)), "69000") s.Equal(fmt.Sprintf("%d", out[2].(uint64)), "69") } + + s.T().Log("test IOracle.chainLinkLatestRoundData") + { + secondsLater := deps.Ctx.BlockTime().Add(100 * time.Second) + ctx := deps.Ctx. + WithBlockTime(secondsLater). + WithBlockHeight(deps.Ctx.BlockHeight() + 50) + resp, err := deps.EvmKeeper.CallContract( + ctx, + embeds.SmartContract_Oracle.ABI, + deps.Sender.EthAddr, + &precompile.PrecompileAddr_Oracle, + false, + OracleGasLimitQuery, + "chainLinkLatestRoundData", + "unibi:uusd", + ) + s.NoError(err) + + // Check the response + out, err := embeds.SmartContract_Oracle.ABI.Unpack( + string(precompile.OracleMethod_chainLinkLatestRoundData), resp.Ret, + ) + s.NoError(err) + // roundId : created at block height 69 + s.Equal(out[0].(*big.Int), big.NewInt(69)) + // answer : exchange rate with 18 decimals. + // In this case, 0.067 = 67 * 10^{15}. + s.Equal(out[1].(*big.Int), big.NewInt(67_000_000_000_000_000)) + // startedAt, updatedAt : created at block timestamp + s.Equal(out[2].(*big.Int), new(big.Int).SetInt64(deps.Ctx.BlockTime().Unix())) + s.Equal(out[3].(*big.Int), new(big.Int).SetInt64(deps.Ctx.BlockTime().Unix())) + // answeredInRound + s.Equal(out[4].(*big.Int), big.NewInt(420)) + } } type OracleSuite struct {