Skip to content

Commit

Permalink
add custom errors
Browse files Browse the repository at this point in the history
  • Loading branch information
josemarinas committed Aug 14, 2023
1 parent fcd99cd commit 065c117
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 32 deletions.
1 change: 1 addition & 0 deletions modules/client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ TEMPLATE:
## [UPCOMING]
### Added
- Block param on `getVotingSettings` and `getMembers` functions to allow for historical data
- `isTokenGovernanceCompatible` function
## 1.11.0-rc1
### Added
- Support for baseMainnet network
Expand Down
40 changes: 17 additions & 23 deletions modules/client/src/tokenVoting/internal/client/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ import {
UNSUPPORTED_PROPOSAL_METADATA_LINK,
} from "@aragon/sdk-client-common";
import {
ERC165_INTERFACE_ID,
ERC20_INTERFACE_ID,
GOVERNANCE_INTERFACES_SUPPORTED,
INSTALLATION_ABI,
TOKEN_INTERFACES_REQUIRED,
Expand All @@ -107,6 +109,10 @@ import {
// import { abi as ERC20_VOTES_ABI } from "@openzeppelin/contracts/build/contracts/ERC20Votes.json";
import { abi as ERC165_ABI } from "@openzeppelin/contracts/build/contracts/ERC165.json";
import { Contract } from "@ethersproject/contracts";
import { ERC165NotSupportedError } from "@aragon/sdk-common";
import { ERC20NotSupportedError } from "@aragon/sdk-common";
import { GoveranceNotSupportedError } from "@aragon/sdk-common";
import { NotAContractError } from "@aragon/sdk-common";

/**
* Methods module the SDK TokenVoting Client
Expand Down Expand Up @@ -749,16 +755,7 @@ export class TokenVotingClientMethods extends ClientCore
}

/**
*Check valid address
chck if its a contract, if not return message
if is contract, check if it supports ERC165
if erc165 is true,
- check if ERC20 or ERCUpgradeable
CHECK:
IVotes or
IVotesUpgradeable or
GovernaceErc20 or
GovernaceWrappedErc20 or
* Checks if the given token is compatible with the TokenVoting plugin
*
* @param {string} tokenAddress
* @return {*} {Promise<boolean>}
Expand All @@ -768,38 +765,35 @@ export class TokenVotingClientMethods extends ClientCore
tokenAddress: string,
): Promise<boolean> {
const signer = this.web3.getConnectedSigner();
if(!isAddress(tokenAddress)) {
if (!isAddress(tokenAddress)) {
throw new InvalidAddressError();
}
const provider = this.web3.getProvider();
if (await provider.getCode(tokenAddress) === "0x") {
throw new Error("not a contract");
throw new NotAContractError();
}
const contract = new Contract(
tokenAddress,
ERC165_ABI,
signer,
);
// TODO: check if is a contract
// TODO: check if is a contract
try {
for (const iface of TOKEN_INTERFACES_REQUIRED) {
const isSupported = await contract.supportsInterface(iface);
if (!isSupported) {
// TODO: throw a custom error
throw new Error();
}
if (!await contract.supportsInterface(ERC165_INTERFACE_ID)) {
throw new ERC165NotSupportedError();
}
if (!await contract.supportsInterface(ERC20_INTERFACE_ID)) {
throw new ERC20NotSupportedError();
}
for (const iface of GOVERNANCE_INTERFACES_SUPPORTED) {
const isSupported = await contract.supportsInterface(iface);
if (isSupported) {
return true;
}
}
// TODO: throw a custom error
throw new Error();
throw new GoveranceNotSupportedError();
} catch {
// if it thorws, means it does not impolement The ERC165 interface
throw new Error();
throw new ERC165NotSupportedError();
}
}
}
10 changes: 6 additions & 4 deletions modules/client/src/tokenVoting/internal/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ export const ERC20_FUNCTIONS = [
"function allowance(address _owner, address _spender) public view returns (uint256 remaining)",
];

export const TOKEN_INTERFACES_REQUIRED = [
getInterfaceId(new Interface(ERC165_ABI)),
getInterfaceId(new Interface(ERC20_FUNCTIONS)),
];
export const ERC20_INTERFACE_ID = getInterfaceId(
new Interface(ERC20_FUNCTIONS),
);
export const ERC165_INTERFACE_ID = getInterfaceId(
new Interface(ERC165_ABI),
);

export const GOVERNANCE_INTERFACES_SUPPORTED = [
getInterfaceId(new Interface(IVOTES_UPGRADEABLE_ABI)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import * as ganacheSetup from "../../helpers/ganache-setup";
import * as deployContracts from "../../helpers/deployContracts";

import {
ERC165NotSupportedError,
ERC20NotSupportedError,
getExtendedProposalId,
InvalidAddressOrEnsError,
} from "@aragon/sdk-common";
Expand Down Expand Up @@ -1443,25 +1445,25 @@ describe("Token Voting Client", () => {
expect(token).toBe(null);
});

it("Should check if a ERC20 is compatible with governance and return false", async () => {
it("Should check if a ERC20 is compatible with governance and throw", async () => {
const ctx = new Context(contextParamsLocalChain);
const client = new TokenVotingClient(ctx);
const erc20Token = await deployErc20();
expect(() =>
client.methods.isTokenGovernanceCompatible(
erc20Token.address,
)
).rejects.toThrow();
).rejects.toThrow(new ERC165NotSupportedError());
});
it("Should check if ERC721 is compatible with governance and return false", async () => {
it("Should check if ERC721 is compatible with governance and throw", async () => {
const ctx = new Context(contextParamsLocalChain);
const client = new TokenVotingClient(ctx);
const erc721Token = await deployErc721();
expect(() =>
client.methods.isTokenGovernanceCompatible(
erc721Token.address,
)
).rejects.toThrow();
).rejects.toThrow(new ERC20NotSupportedError());
});
it("Should check if GovernanceERC20 is compatible with governance and return true", async () => {
const ctx = new Context(contextParamsLocalChain);
Expand Down
4 changes: 3 additions & 1 deletion modules/common/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ TEMPLATE:
-->

## [UPCOMING]

### Added
- New error classes
- `getInterfaceId` function
## 1.5.0
### Added
- New error classes `SizeMismatchError`, `InvalidProposalStatusError`, `NotImplementedError`, `InvalidActionError`, `InvalidSubdomainError`, `InvalidGasEstimationFactorError` and `UseTransferError`
Expand Down
33 changes: 33 additions & 0 deletions modules/common/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,36 @@ export class InvalidGasEstimationFactorError extends SdkError {
);
}
}
export class NotAContractError extends SdkError {
constructor(cause?: Error) {
super(
"The provided address does not point to a contract or the contract is not deployed",
cause,
);
}
}

export class ERC165NotSupportedError extends SdkError {
constructor(cause?: Error) {
super(
"ERC165 is not supported by the contract at the provided address",
cause,
);
}
}
export class ERC20NotSupportedError extends SdkError {
constructor(cause?: Error) {
super(
"ERC20 is not supported by the contract at the provided address",
cause,
);
}
}
export class GoveranceNotSupportedError extends SdkError {
constructor(cause?: Error) {
super(
"The contract at the provided address does not support governance",
cause,
);
}
}

0 comments on commit 065c117

Please sign in to comment.