From 64dd6a12e42327690d81d6de24c3ce7370ac239c Mon Sep 17 00:00:00 2001 From: Aleksa Opacic Date: Tue, 24 Sep 2024 13:54:35 +0200 Subject: [PATCH] remove user wallet (#15) --- contracts/UserWallet.sol | 20 ---------------- ignition/modules/User.ts | 7 ------ ignition/parameters.json | 3 --- tasks/core/pair/burn.ts | 39 ++++++++++++++++++++---------- tasks/core/pair/mint.ts | 50 ++++++++++++++++++++++++++------------- tasks/core/pair/swap.ts | 51 +++++++++++++++++++++++++--------------- tasks/util/client.ts | 38 ++++++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 78 deletions(-) delete mode 100644 contracts/UserWallet.sol delete mode 100644 ignition/modules/User.ts create mode 100644 tasks/util/client.ts diff --git a/contracts/UserWallet.sol b/contracts/UserWallet.sol deleted file mode 100644 index 3f81cd3..0000000 --- a/contracts/UserWallet.sol +++ /dev/null @@ -1,20 +0,0 @@ -// In another contract, e.g., MainContract.sol -import "@nilfoundation/smart-contracts/contracts/Wallet.sol"; - -contract UserWallet is NilCurrencyBase { - Wallet public wallet; - - constructor(bytes memory _pubkey) { - wallet = new Wallet(_pubkey); - } - receive() external payable {} - - /** - * @dev Sends currency to a specified address - * This is a workaround until we are able to send external messages to smart contracts - * For production, consider implementing access control, such as Ownable from OpenZeppelin - */ - function sendCurrencyPublic(address to, uint256 currencyId, uint256 amount) public { - sendCurrencyInternal(to, currencyId, amount); - } -} \ No newline at end of file diff --git a/ignition/modules/User.ts b/ignition/modules/User.ts deleted file mode 100644 index 28f52f4..0000000 --- a/ignition/modules/User.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; - -module.exports = buildModule("DeployUser", (m) => { - const token = m.contract("UserWallet", [m.getParameter("publicKey", "")]); - - return { token }; -}); diff --git a/ignition/parameters.json b/ignition/parameters.json index e332723..0d1455b 100644 --- a/ignition/parameters.json +++ b/ignition/parameters.json @@ -7,8 +7,5 @@ }, "DeployUniswapV2Router01": { "factory": "0x0000000000000000000000000000000000000000" - }, - "DeployUser": { - "publicKey": "0x0000000000000000000000000000000000000000" } } diff --git a/tasks/core/pair/burn.ts b/tasks/core/pair/burn.ts index 410329e..bbbaff6 100644 --- a/tasks/core/pair/burn.ts +++ b/tasks/core/pair/burn.ts @@ -1,14 +1,22 @@ +import { shardNumber } from "@nilfoundation/hardhat-plugin/dist/utils/conversion"; +import { waitTillCompleted } from "@nilfoundation/niljs"; import { task } from "hardhat/config"; import type { Currency, UniswapV2Pair } from "../../../typechain-types"; -import type { UserWallet } from "../../../typechain-types"; +import { createClient } from "../../util/client"; task("burn", "Burn liquidity tokens and print balances and reserves") .addParam("pair", "The address of the pair contract") - .addParam("wallet", "The address to transfer the burned tokens to") .setAction(async (taskArgs, hre) => { + const walletAddress = process.env.WALLET_ADDR; + + if (!walletAddress) { + throw new Error("WALLET_ADDR is not set in environment variables"); + } + + const { wallet, publicClient } = await createClient(); + // Destructure parameters for clarity const pairAddress = taskArgs.pair; - const walletAddress = taskArgs.wallet; // Attach to the Uniswap V2 Pair contract const Pair = await hre.ethers.getContractFactory("UniswapV2Pair"); @@ -57,20 +65,25 @@ task("burn", "Burn liquidity tokens and print balances and reserves") userBalanceToken1.toString(), ); - // Attach to the UserWallet contract - const UserFactory = await hre.ethers.getContractFactory("UserWallet"); - const user = UserFactory.attach(walletAddress) as UserWallet; - const lpAddress = await pair.getCurrencyId(); const userLpBalance = await pair.getCurrencyBalanceOf(walletAddress); console.log("Total LP balance for user wallet:", userLpBalance.toString()); - // Send LP tokens to the user wallet - await user.sendCurrencyPublic( - pairAddress.toLowerCase(), - lpAddress, - userLpBalance, - ); + const hash = await wallet.sendMessage({ + // @ts-ignore + to: pairAddress, + feeCredit: BigInt(10_000_000), + value: BigInt(0), + refundTo: walletAddress, + tokens: [ + { + id: lpAddress, + amount: BigInt(userLpBalance), + }, + ], + }); + + await waitTillCompleted(publicClient, shardNumber(walletAddress), hash); // Execute burn console.log("Executing burn..."); diff --git a/tasks/core/pair/mint.ts b/tasks/core/pair/mint.ts index c0fe2b3..7cdbc76 100644 --- a/tasks/core/pair/mint.ts +++ b/tasks/core/pair/mint.ts @@ -1,19 +1,24 @@ +import { shardNumber } from "@nilfoundation/hardhat-plugin/dist/utils/conversion"; +import { waitTillCompleted } from "@nilfoundation/niljs"; import { task } from "hardhat/config"; -import type { - Currency, - UniswapV2Pair, - UserWallet, -} from "../../../typechain-types"; +import type { Currency, UniswapV2Pair } from "../../../typechain-types"; +import { createClient } from "../../util/client"; task("mint", "Mint currencies and add liquidity to the pair") .addParam("pair", "The address of the pair contract") - .addParam("wallet", "The address of the user contract") .addParam("amount0", "The amount of the first currency to mint") .addParam("amount1", "The amount of the second currency to mint") .setAction(async (taskArgs, hre) => { + const walletAddress = process.env.WALLET_ADDR; + + if (!walletAddress) { + throw new Error("WALLET_ADDR is not set in environment variables"); + } + + const { wallet, publicClient } = await createClient(); + // Destructure parameters for clarity const pairAddress = taskArgs.pair; - const walletAddress = taskArgs.wallet; const amount0 = taskArgs.amount0; const amount1 = taskArgs.amount1; @@ -40,16 +45,29 @@ task("mint", "Mint currencies and add liquidity to the pair") const currency1Id = await currency1.getCurrencyId(); console.log("Currency 1 ID:", currency1Id); - // Attach to the UserWallet contract - const UserFactory = await hre.ethers.getContractFactory("UserWallet"); - const user = UserFactory.attach(walletAddress) as UserWallet; - // Send currency amounts to the pair contract - console.log(`Sending ${amount0} of currency0 to ${pairAddress}...`); - await user.sendCurrencyPublic(pairAddress, currency0Id, amount0); - - console.log(`Sending ${amount1} of currency1 to ${pairAddress}...`); - await user.sendCurrencyPublic(pairAddress, currency1Id, amount1); + console.log( + `Sending ${amount0} currency0 and ${amount1} currency1 to ${pairAddress}...`, + ); + const hash = await wallet.sendMessage({ + // @ts-ignore + to: pairAddress, + feeCredit: BigInt(10_000_000), + value: BigInt(0), + refundTo: wallet.address, + tokens: [ + { + id: currency0Id, + amount: BigInt(amount0), + }, + { + id: currency1Id, + amount: BigInt(amount1), + }, + ], + }); + + await waitTillCompleted(publicClient, shardNumber(walletAddress), hash); // Log balances in the pair contract const pairCurrency0Balance = diff --git a/tasks/core/pair/swap.ts b/tasks/core/pair/swap.ts index abc21f0..9abed4f 100644 --- a/tasks/core/pair/swap.ts +++ b/tasks/core/pair/swap.ts @@ -1,17 +1,22 @@ +import { shardNumber } from "@nilfoundation/hardhat-plugin/dist/utils/conversion"; +import { waitTillCompleted } from "@nilfoundation/niljs"; import { task } from "hardhat/config"; -import type { - Currency, - UniswapV2Pair, - UserWallet, -} from "../../../typechain-types"; +import type { Currency, UniswapV2Pair } from "../../../typechain-types"; +import { createClient } from "../../util/client"; task("swap", "Swap currency0 for currency1 in the Uniswap pair") .addParam("pair", "The address of the Uniswap pair contract") - .addParam("wallet", "The address of the user which is swapping") .addParam("amount", "The amount of currency0 to swap") .setAction(async (taskArgs, hre) => { + const walletAddress = process.env.WALLET_ADDR; + + if (!walletAddress) { + throw new Error("WALLET_ADDR is not set in environment variables"); + } + + const { wallet, publicClient } = await createClient(); + // Destructure parameters for clarity - const userWalletAddress = taskArgs.wallet.toLowerCase(); const pairAddress = taskArgs.pair.toLowerCase(); const swapAmount = BigInt(taskArgs.amount); @@ -61,9 +66,9 @@ task("swap", "Swap currency0 for currency1 in the Uniswap pair") // Log balances before the swap const balanceCurrency0Before = - await currency0Contract.getCurrencyBalanceOf(userWalletAddress); + await currency0Contract.getCurrencyBalanceOf(walletAddress); const balanceCurrency1Before = - await currency1Contract.getCurrencyBalanceOf(userWalletAddress); + await currency1Contract.getCurrencyBalanceOf(walletAddress); console.log( "Balance of currency0 before swap:", balanceCurrency0Before.toString(), @@ -73,28 +78,36 @@ task("swap", "Swap currency0 for currency1 in the Uniswap pair") balanceCurrency1Before.toString(), ); - // Attach to the UserWallet contract - const UserWalletFactory = await hre.ethers.getContractFactory("UserWallet"); - const userWallet = UserWalletFactory.attach( - userWalletAddress, - ) as UserWallet; + const hash = await wallet.sendMessage({ + // @ts-ignore + to: pairAddress, + feeCredit: BigInt(10_000_000), + value: BigInt(0), + refundTo: wallet.address, + tokens: [ + { + id: currency0Id, + amount: BigInt(swapAmount), + }, + ], + }); + + await waitTillCompleted(publicClient, shardNumber(walletAddress), hash); - // Send currency0 to the pair contract - await userWallet.sendCurrencyPublic(pairAddress, currency0Id, swapAmount); console.log( `Sent ${swapAmount.toString()} of currency0 to the pair contract.`, ); // Execute the swap console.log("Executing swap..."); - await pair.swap(0, expectedOutputAmount, userWalletAddress); + await pair.swap(0, expectedOutputAmount, walletAddress); console.log("Swap executed successfully."); // Log balances after the swap const balanceCurrency0After = - await currency0Contract.getCurrencyBalanceOf(userWalletAddress); + await currency0Contract.getCurrencyBalanceOf(walletAddress); const balanceCurrency1After = - await currency1Contract.getCurrencyBalanceOf(userWalletAddress); + await currency1Contract.getCurrencyBalanceOf(walletAddress); console.log( "Balance of currency0 after swap:", balanceCurrency0After.toString(), diff --git a/tasks/util/client.ts b/tasks/util/client.ts new file mode 100644 index 0000000..64364c9 --- /dev/null +++ b/tasks/util/client.ts @@ -0,0 +1,38 @@ +import { + HttpTransport, + LocalECDSAKeySigner, + PublicClient, + WalletV1, +} from "@nilfoundation/niljs"; + +export async function createClient(): Promise<{ + wallet: WalletV1; + publicClient: PublicClient; +}> { + const walletAddress = process.env.WALLET_ADDR; + + if (!walletAddress) { + throw new Error("WALLET_ADDR is not set in environment variables"); + } + + const publicClient = new PublicClient({ + transport: new HttpTransport({ + endpoint: walletAddress, + }), + shardId: 1, + }); + + const signer = new LocalECDSAKeySigner({ + privateKey: `0x${process.env.PRIVATE_KEY}`, + }); + const pubkey = await signer.getPublicKey(); + + const wallet = new WalletV1({ + pubkey: pubkey, + address: walletAddress, + client: publicClient, + signer, + }); + + return { wallet, publicClient }; +}