From 1d9105efadce88cc1963424ad6029422020cfd21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Manuel=20Mari=C3=B1as=20Bascoy?= Date: Mon, 24 Jul 2023 17:25:44 +0200 Subject: [PATCH] fix comments --- modules/client/src/internal/client/methods.ts | 96 +++---------- modules/client/src/internal/utils.ts | 126 +++++++++++++++--- .../test/integration/client/encoding.test.ts | 2 + 3 files changed, 126 insertions(+), 98 deletions(-) diff --git a/modules/client/src/internal/client/methods.ts b/modules/client/src/internal/client/methods.ts index 914e66751..98331cc96 100644 --- a/modules/client/src/internal/client/methods.ts +++ b/modules/client/src/internal/client/methods.ts @@ -7,9 +7,7 @@ import { PluginSetupProcessor__factory, } from "@aragon/osx-ethers"; import { - AmountMismatchError, DaoCreationError, - FailedDepositError, InstallationNotFoundError, InvalidAddressOrEnsError, InvalidCidError, @@ -30,7 +28,6 @@ import { BigNumber } from "@ethersproject/bignumber"; import { AddressZero } from "@ethersproject/constants"; import { Contract, ContractTransaction } from "@ethersproject/contracts"; import { abi as ERC20_ABI } from "@openzeppelin/contracts/build/contracts/ERC20Votes.json"; -import { abi as ERC721_ABI } from "@openzeppelin/contracts/build/contracts/ERC721.json"; import { QueryDao, QueryDaos, @@ -84,6 +81,8 @@ import { SubgraphTransferTypeMap, } from "../types"; import { + depositErc20, + depositErc721, toAssetBalance, toDaoDetails, toDaoListItem, @@ -91,7 +90,6 @@ import { toPluginRepoListItem, toPluginRepoRelease, toTokenTransfer, - unwrapDepositParams, } from "../utils"; import { isAddress } from "@ethersproject/address"; import { toUtf8Bytes } from "@ethersproject/strings"; @@ -278,20 +276,22 @@ export class ClientMethods extends ClientCore implements IClientMethods { params: DepositParams, ): AsyncGenerator { const signer = this.web3.getConnectedSigner(); - + // check if is a supported token if ( - params.type !== TokenType.NATIVE && params.type !== TokenType.ERC20 && - params.type !== TokenType.ERC721 + ![TokenType.NATIVE, TokenType.ERC20, TokenType.ERC721].includes( + params.type, + ) ) { throw new UseTransferError(); } if (params.type === TokenType.ERC20 || params.type === TokenType.NATIVE) { - const [daoAddress, amount, tokenAddress, reference] = unwrapDepositParams( - params, - ); - - if (tokenAddress && tokenAddress !== AddressZero) { + // check and update allowance if needed + if ( + params.type === TokenType.ERC20 && params.tokenAddress && + params.tokenAddress !== AddressZero + ) { + const { tokenAddress, daoAddressOrEns } = params; // check current allowance const tokenInstance = new Contract( tokenAddress, @@ -300,7 +300,7 @@ export class ClientMethods extends ClientCore implements IClientMethods { ); const currentAllowance = await tokenInstance.allowance( await signer.getAddress(), - daoAddress, + daoAddressOrEns, ); yield { key: DaoDepositSteps.CHECKED_ALLOWANCE, @@ -313,79 +313,15 @@ export class ClientMethods extends ClientCore implements IClientMethods { yield* this.setAllowance( { amount: params.amount, - spender: daoAddress, + spender: daoAddressOrEns, tokenAddress, }, ); } } - - // Doing the transfer - const daoInstance = DAO__factory.connect(daoAddress, signer); - const override: { value?: bigint } = {}; - - if (tokenAddress === AddressZero) { - // Ether - override.value = amount; - } - - const tx = await daoInstance.deposit( - tokenAddress, - amount, - reference, - override, - ); - yield { key: DaoDepositSteps.DEPOSITING, txHash: tx.hash }; - - const cr = await tx.wait(); - const log = findLog(cr, daoInstance.interface, "Deposited"); - if (!log) { - throw new FailedDepositError(); - } - - const daoInterface = DAO__factory.createInterface(); - const parsedLog = daoInterface.parseLog(log); - - if (!amount.toString() === parsedLog.args["amount"]) { - throw new AmountMismatchError( - amount, - parsedLog.args["amount"].toBigInt(), - ); - } - yield { key: DaoDepositSteps.DONE, amount: amount }; + yield* depositErc20(signer, params); } else if (params.type === TokenType.ERC721) { - const nftInstance = new Contract( - params.tokenAddress, - ERC721_ABI, - signer, - ); - - // Doing the transfer - const tx = await nftInstance["safeTransferFrom(address,address,uint256)"]( - await signer.getAddress(), - params.daoAddressOrEns, - params.tokenId, - ); - - const cr = await tx.wait(); - - const log = findLog(cr, nftInstance.interface, "Transfer"); - - if (!log) { - throw new FailedDepositError(); - } - - const parsedLog = nftInstance.interface.parseLog(log); - if ( - !parsedLog.args["tokenId"] || - parsedLog.args["tokenId"].toString() !== params.tokenId.toString() - ) { - throw new FailedDepositError(); - } - yield { - key: DaoDepositSteps.DONE, - tokenId: params.tokenId, - }; + yield* depositErc721(signer, params); } else { throw new NotImplementedError("Token type not implemented"); } diff --git a/modules/client/src/internal/utils.ts b/modules/client/src/internal/utils.ts index 1eba47ce2..90774953b 100644 --- a/modules/client/src/internal/utils.ts +++ b/modules/client/src/internal/utils.ts @@ -1,10 +1,13 @@ import { ApplyUninstallationParams, AssetBalance, + DaoDepositSteps, + DaoDepositStepValue, DaoDetails, DaoListItem, DaoMetadata, DepositErc20Params, + DepositErc721Params, DepositEthParams, GrantPermissionDecodedParams, GrantPermissionParams, @@ -39,14 +42,18 @@ import { defaultAbiCoder, Result } from "@ethersproject/abi"; import { keccak256 } from "@ethersproject/keccak256"; import { toUtf8Bytes } from "@ethersproject/strings"; import { AddressZero } from "@ethersproject/constants"; -import { PluginSetupProcessor } from "@aragon/osx-ethers"; +import { DAO__factory, PluginSetupProcessor } from "@aragon/osx-ethers"; import { PermissionIds } from "../constants"; import { ApplyInstallationParams, DecodedApplyInstallationParams, + findLog, TokenType, } from "@aragon/sdk-client-common"; -import { NotImplementedError } from "@aragon/sdk-common"; +import { AmountMismatchError, FailedDepositError, NotImplementedError } from "@aragon/sdk-common"; +import { Signer } from "@ethersproject/abstract-signer"; +import { Contract } from "@ethersproject/contracts"; +import { abi as ERC721_ABI } from "@openzeppelin/contracts/build/contracts/ERC721.json"; export function unwrapDepositParams( params: DepositEthParams | DepositErc20Params, @@ -76,7 +83,9 @@ export function toDaoDetails( // TODO update when new subgraph schema is deployed // filter out plugins that are not applied plugins: dao.plugins.filter( - (plugin) => plugin.appliedPreparation && plugin.appliedVersion && plugin.appliedPluginRepo, + (plugin) => + plugin.appliedPreparation && plugin.appliedVersion && + plugin.appliedPluginRepo, ) .map( ( @@ -107,21 +116,23 @@ export function toDaoListItem( avatar: metadata.avatar || undefined, }, plugins: dao.plugins.filter( - (plugin) => plugin.appliedPreparation && plugin.appliedVersion && plugin.appliedPluginRepo, + (plugin) => + plugin.appliedPreparation && plugin.appliedVersion && + plugin.appliedPluginRepo, ) - .map( - ( - plugin: SubgraphPluginListItem, - ): InstalledPluginListItem => ( - { - // we checked with the filter above that these are not null - id: `${plugin.appliedPluginRepo!.subdomain}.plugin.dao.eth`, - release: plugin.appliedVersion!.release.release, - build: plugin.appliedVersion!.build, - instanceAddress: plugin.appliedPreparation!.pluginAddress, - } + .map( + ( + plugin: SubgraphPluginListItem, + ): InstalledPluginListItem => ( + { + // we checked with the filter above that these are not null + id: `${plugin.appliedPluginRepo!.subdomain}.plugin.dao.eth`, + release: plugin.appliedVersion!.release.release, + build: plugin.appliedVersion!.build, + instanceAddress: plugin.appliedPreparation!.pluginAddress, + } + ), ), - ), }; } @@ -395,9 +406,88 @@ export function withdrawParamsFromContract( recipientAddressOrEns: result[1], tokenId: BigInt(result[2]), daoAddressOrEns: result[0], - } + }; } - // TODO Add ERC721 and ERC1155 + // TODO Add ERC1155 throw new NotImplementedError("Token standard not supported"); } + +export async function* depositErc721( + signer: Signer, + params: DepositErc721Params, +): AsyncGenerator { + const erc721Contract = new Contract(params.tokenAddress, ERC721_ABI, signer); + const tx = await erc721Contract["safeTransferFrom(address,address,uint256)"]( + await signer.getAddress(), + params.daoAddressOrEns, + params.tokenId, + ); + + const cr = await tx.wait(); + + const log = findLog(cr, erc721Contract.interface, "Transfer"); + + if (!log) { + throw new FailedDepositError(); + } + + const parsedLog = erc721Contract.interface.parseLog(log); + if ( + !parsedLog.args["tokenId"] || + parsedLog.args["tokenId"].toString() !== params.tokenId.toString() + ) { + throw new FailedDepositError(); + } + yield { + key: DaoDepositSteps.DONE, + tokenId: params.tokenId, + }; +} + +export async function* depositErc20( + signer: Signer, + params: DepositErc20Params | DepositEthParams, +): AsyncGenerator { + let tokenAddress = AddressZero; + if (params.type === TokenType.ERC20) { + tokenAddress = params.tokenAddress; + } + const { + amount, + daoAddressOrEns, + } = params; + // Doing the transfer + const daoInstance = DAO__factory.connect(daoAddressOrEns, signer); + const override: { value?: bigint } = {}; + + if (tokenAddress === AddressZero) { + // Ether + override.value = params.amount; + } + + const tx = await daoInstance.deposit( + tokenAddress, + amount, + "", + override, + ); + yield { key: DaoDepositSteps.DEPOSITING, txHash: tx.hash }; + + const cr = await tx.wait(); + const log = findLog(cr, daoInstance.interface, "Deposited"); + if (!log) { + throw new FailedDepositError(); + } + + const daoInterface = DAO__factory.createInterface(); + const parsedLog = daoInterface.parseLog(log); + + if (!amount.toString() === parsedLog.args["amount"]) { + throw new AmountMismatchError( + amount, + parsedLog.args["amount"].toBigInt(), + ); + } + yield { key: DaoDepositSteps.DONE, amount: amount }; +} diff --git a/modules/client/test/integration/client/encoding.test.ts b/modules/client/test/integration/client/encoding.test.ts index 9e31801bf..38e7b6c13 100644 --- a/modules/client/test/integration/client/encoding.test.ts +++ b/modules/client/test/integration/client/encoding.test.ts @@ -104,6 +104,8 @@ describe("Client", () => { expect(typeof withdrawAction).toBe("object"); expect(withdrawAction.data).toBeInstanceOf(Uint8Array); + expect(withdrawAction.to).toBe(withdrawParams.tokenAddress); + expect(withdrawAction.value).toBe(BigInt(0)); expect(bytesToHex(withdrawAction.data)).toBe( "0x42842e0e00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a", );