From ccaf3e596a5d17e07fe06ad060edbc55122175b1 Mon Sep 17 00:00:00 2001 From: g1nt0ki <99907941+g1nt0ki@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:45:13 +0200 Subject: [PATCH] dolomite: handle custom tokens --- package-lock.json | 14 ++-- projects/dolomite/index.js | 16 ++-- utils/contracts/TestUniQuery.sol | 31 ++++++++ utils/contracts/UniV2TVL.sol | 100 ++++++++++++++++++++++++ utils/package-lock.json | 126 +++++++++++++++++++++++++++++-- utils/package.json | 3 +- utils/scripts/testBatchCall.js | 24 ++++++ utils/scripts/testCompiler.js | 28 +++++++ 8 files changed, 323 insertions(+), 19 deletions(-) create mode 100644 utils/contracts/TestUniQuery.sol create mode 100644 utils/contracts/UniV2TVL.sol create mode 100644 utils/scripts/testBatchCall.js create mode 100644 utils/scripts/testCompiler.js diff --git a/package-lock.json b/package-lock.json index 4837c7294..6a48860ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,9 +63,9 @@ } }, "node_modules/@defillama/sdk": { - "version": "4.0.26", - "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-4.0.26.tgz", - "integrity": "sha512-qZ0aZHocHhpWC/Mis/rvc/CCOs1Z+MCbLIVSVfJi/6d4acOzgV5m+oLtxVK1Rz0bsMrPZHdT+kUFkum8EKPodw==", + "version": "4.0.28", + "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-4.0.28.tgz", + "integrity": "sha512-0mqCkiy1pOhZgLCQ/RSdHyuPvchoIoOWj0JIRzFnUAV9uEP6Pck/EqYNB4PpoonZqWAqBDM2cGN1/qj/WQUUtw==", "dependencies": { "@supercharge/promise-pool": "^2.1.0", "ethers": "^5.4.5", @@ -4194,9 +4194,9 @@ } }, "@defillama/sdk": { - "version": "4.0.26", - "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-4.0.26.tgz", - "integrity": "sha512-qZ0aZHocHhpWC/Mis/rvc/CCOs1Z+MCbLIVSVfJi/6d4acOzgV5m+oLtxVK1Rz0bsMrPZHdT+kUFkum8EKPodw==", + "version": "4.0.28", + "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-4.0.28.tgz", + "integrity": "sha512-0mqCkiy1pOhZgLCQ/RSdHyuPvchoIoOWj0JIRzFnUAV9uEP6Pck/EqYNB4PpoonZqWAqBDM2cGN1/qj/WQUUtw==", "requires": { "@supercharge/promise-pool": "^2.1.0", "ethers": "^5.4.5", @@ -6791,7 +6791,7 @@ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "ansi-regex": "5.0.1" } }, "strip-json-comments": { diff --git a/projects/dolomite/index.js b/projects/dolomite/index.js index f02d934a6..abc387440 100644 --- a/projects/dolomite/index.js +++ b/projects/dolomite/index.js @@ -3,17 +3,23 @@ const { getMarketTokenAddress, getMarketTotalPar, } = require("./dolomite-margin.json"); -const { sumTokens2 } = require('../helper/unwrapLPs') const dolomiteMargin = "0x6bd780e7fdf01d77e4d475c821f1e7ae05409072"; async function getTokensAndBalances(api, supplyOrBorrow) { const tokens = await api.fetchList({ lengthAbi: getNumMarkets, itemAbi: getMarketTokenAddress, target: dolomiteMargin }) - if (supplyOrBorrow === 'supply') - return sumTokens2({ owner: dolomiteMargin, api, tokens }) + const underlyingTokens = await api.multiCall({ abi: 'address:UNDERLYING_TOKEN', calls: tokens, permitFailure: true, }) + let bals + if (supplyOrBorrow === 'supply') { + bals = await api.multiCall({ abi: 'erc20:balanceOf', calls: tokens.map(i => ({ target: i, params: dolomiteMargin })), }) - const res = await api.fetchList({ lengthAbi: getNumMarkets, itemAbi: getMarketTotalPar, target: dolomiteMargin }) - res.forEach((v, i) => api.addToken(tokens[i], v.borrow)) + } else { + const res = await api.fetchList({ lengthAbi: getNumMarkets, itemAbi: getMarketTotalPar, target: dolomiteMargin }) + bals = res.map(i => i.borrow) + } + tokens.forEach((v, i) => { + api.add(underlyingTokens[i] ?? v, bals[i]) + }) } async function tvl(timestamp, ethereumBlock, blocksToKeys, { api }) { diff --git a/utils/contracts/TestUniQuery.sol b/utils/contracts/TestUniQuery.sol new file mode 100644 index 000000000..44587597d --- /dev/null +++ b/utils/contracts/TestUniQuery.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IUniswapV2Factory { + function allPairsLength() external view returns (uint); + + function allPairs(uint) external view returns (address); +} + +contract TestUniQuery { + constructor(address factory) { + IUniswapV2Factory uniswapFactory = IUniswapV2Factory(factory); + uint pairCount = uniswapFactory.allPairsLength(); + + // encode the return data + bytes memory _data = abi.encode(pairCount); + // force constructor to return data via assembly + assembly { + // abi.encode adds an additional offset (32 bytes) that we need to skip + let _dataStart := add(_data, 32) + // msize() gets the size of active memory in bytes. + // if we subtract msize() from _dataStart, the output will be + // the amount of bytes from _dataStart to the end of memory + // which due to how the data has been laid out in memory, will coincide with + // where our desired data ends. + let _dataEnd := sub(msize(), _dataStart) + // starting from _dataStart, get all the data in memory. + return(_dataStart, _dataEnd) + } + } +} diff --git a/utils/contracts/UniV2TVL.sol b/utils/contracts/UniV2TVL.sol new file mode 100644 index 000000000..87521b1a9 --- /dev/null +++ b/utils/contracts/UniV2TVL.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IUniswapV2Pair { + function token0() external view returns (address); + + function token1() external view returns (address); + + function getReserves() + external + view + returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); +} + +interface IUniswapV2Factory { + function allPairsLength() external view returns (uint); + + function allPairs(uint) external view returns (address); +} + +contract UniV2TVL { + struct KeyValuePair { + address key; + uint value; + } + + mapping(address => uint) public tvlMap; + mapping(address => bool) public isBaseToken; + address[] public tokens; + + constructor( + address factory, + address[] memory baseTokens, + bool includeQuoteTokens, + uint startIndex, + uint endIndex + ) { + IUniswapV2Factory uniswapFactory = IUniswapV2Factory(factory); + uint pairCount = uniswapFactory.allPairsLength(); + if (endIndex == 0) endIndex = pairCount; + + // Create a set of base tokens for efficient membership check + for (uint i = startIndex; i < baseTokens.length; i++) { + isBaseToken[baseTokens[i]] = true; + } + + for (uint i = 0; i < pairCount; i++) { + address pairAddress = uniswapFactory.allPairs(i); + IUniswapV2Pair pair = IUniswapV2Pair(pairAddress); + address token0 = pair.token0(); + address token1 = pair.token1(); + uint reserve0; + uint reserve1; + (reserve0, reserve1, ) = pair.getReserves(); + bool isToken0BaseToken = isBaseToken[token0]; + bool isToken1BaseToken = isBaseToken[token1]; + + if ( reserve0 == 0 || reserve1 == 0) continue; + + if (isToken0BaseToken && isToken1BaseToken) { + if (tvlMap[token0] == 0) tokens.push(token0); + if (tvlMap[token1] == 0) tokens.push(token1); + tvlMap[token0] += reserve0; + tvlMap[token1] += reserve1; + } else if (isToken0BaseToken) { + if (tvlMap[token0] == 0) tokens.push(token0); + tvlMap[token0] += reserve0 * 2; + } else if (isToken1BaseToken) { + if (tvlMap[token1] == 0) tokens.push(token1); + tvlMap[token1] += reserve1 * 2; + } else if (includeQuoteTokens) { + if (tvlMap[token0] == 0) tokens.push(token0); + if (tvlMap[token1] == 0) tokens.push(token1); + tvlMap[token0] += reserve0; + tvlMap[token1] += reserve1; + } + } + + KeyValuePair[] memory returnData = new KeyValuePair[](tokens.length); + for (uint i = 0; i < tokens.length; i++) { + returnData[i] = KeyValuePair(tokens[i], tvlMap[tokens[i]]); + } + + // encode the return data + bytes memory _data = abi.encode(returnData); + // force constructor to return data via assembly + assembly { + // abi.encode adds an additional offset (32 bytes) that we need to skip + let _dataStart := add(_data, 32) + // msize() gets the size of active memory in bytes. + // if we subtract msize() from _dataStart, the output will be + // the amount of bytes from _dataStart to the end of memory + // which due to how the data has been laid out in memory, will coincide with + // where our desired data ends. + let _dataEnd := sub(msize(), _dataStart) + // starting from _dataStart, get all the data in memory. + return(_dataStart, _dataEnd) + } + } +} diff --git a/utils/package-lock.json b/utils/package-lock.json index 7747b92ee..6c6646958 100644 --- a/utils/package-lock.json +++ b/utils/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.1", "license": "ISC", "dependencies": { - "glob": "^8.0.3" + "glob": "^8.0.3", + "solc": "^0.8.20" }, "devDependencies": { "inquirer": "^8.2.4", @@ -205,6 +206,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, "node_modules/defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -258,6 +272,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -701,6 +734,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -723,6 +761,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -799,7 +845,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -875,12 +920,40 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/solc": { + "version": "0.8.20", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.20.tgz", + "integrity": "sha512-fPRnGspIEqmhu63RFO3pc79sLA7ZmzO0Uy0L5l6hEt2wAsq0o7UV6pXkAp3Mfv9IBhg7Px/oTu3a+y4gs3BWrQ==", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -938,7 +1011,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -1125,6 +1197,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -1166,6 +1248,11 @@ "escape-string-regexp": "^1.0.5" } }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1505,6 +1592,11 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1521,6 +1613,11 @@ "is-unicode-supported": "^0.1.0" } }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==" + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -1578,8 +1675,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "readable-stream": { "version": "3.6.0", @@ -1629,12 +1725,31 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "solc": { + "version": "0.8.20", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.20.tgz", + "integrity": "sha512-fPRnGspIEqmhu63RFO3pc79sLA7ZmzO0Uy0L5l6hEt2wAsq0o7UV6pXkAp3Mfv9IBhg7Px/oTu3a+y4gs3BWrQ==", + "requires": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -1683,7 +1798,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "requires": { "os-tmpdir": "~1.0.2" } diff --git a/utils/package.json b/utils/package.json index cb2ce215f..49d6ccc56 100644 --- a/utils/package.json +++ b/utils/package.json @@ -13,6 +13,7 @@ "inquirer-fuzzy-path": "^2.3.0" }, "dependencies": { - "glob": "^8.0.3" + "glob": "^8.0.3", + "solc": "^0.8.20" } } diff --git a/utils/scripts/testBatchCall.js b/utils/scripts/testBatchCall.js new file mode 100644 index 000000000..6ae43ae3b --- /dev/null +++ b/utils/scripts/testBatchCall.js @@ -0,0 +1,24 @@ +const ethers = require('ethers') +const { getProvider } = require('@defillama/sdk/build/general') +const fs = require('fs') +const coreAssets = require('../../projects/helper/coreAssets.json') + +const bytecode = fs.readFileSync(__dirname + `/../artifacts/UniV2TVL.bytecode`, 'utf8') +// const inputData = ethers.utils.defaultAbiCoder.encode(['address'], ['0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f']); +const inputData = ethers.utils.defaultAbiCoder.encode(['address', 'address[]', 'bool', 'uint256', 'uint256'], ['0x460b2005b3318982feADA99f7ebF13e1D6f6eFfE', Object.values(coreAssets.ethereum), false, 0, 0]); + +// concatenate the bytecode of BatchPoolManagerData with the input data. +// the slice is done to remove the 0x prefix from the input data added by the encoding +const contractCreationCode = bytecode.concat(inputData.slice(2)); + +const provider = getProvider('ethereum') + +async function main() { + const returnedData = await provider.call({ data: '0x' + contractCreationCode }) + console.log(returnedData) + // decode the returned data to get the array of tuples using the same data types as the Data struct in the PoolManager contract + const [decoded] = ethers.utils.defaultAbiCoder.decode(['tuple(address,uint256)[]'], returnedData); + console.log(decoded) +} + +main() \ No newline at end of file diff --git a/utils/scripts/testCompiler.js b/utils/scripts/testCompiler.js new file mode 100644 index 000000000..eb3dc8df0 --- /dev/null +++ b/utils/scripts/testCompiler.js @@ -0,0 +1,28 @@ +const solc = require('solc'); +const fs = require('fs'); + +const contractName = 'UniV2TVL'; +const contractFile = `${contractName}.sol`; +// Solidity contract code +const solidityCode = fs.readFileSync(__dirname+`/../contracts/${contractFile}`, 'utf8'); + +function compileContract(contractCode) { + const input = { + language: 'Solidity', + sources: { + [contractFile]: { + content: contractCode, + }, + }, + settings: { + outputSelection: { '*': { '*': ['*'], }, }, + }, + }; + + const output = JSON.parse(solc.compile(JSON.stringify(input))); + const bytecode = output.contracts[contractFile][contractName].evm.bytecode.object; + fs.writeFileSync(__dirname+`/../artifacts/${contractName}.bytecode`, bytecode) +} + +// Compile the contract and get the bytecode +compileContract(solidityCode) \ No newline at end of file