Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PP-840: get allowed tokens for given verifiers only #136

Merged
merged 12 commits into from
Oct 19, 2023
12 changes: 7 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ npx hardhat collector:change-partners --collector-address "<collector_address>"
```
Example:
```bash
npx hardhat collector:change-partners --collector-address "<0x9b91c655AaE10E6cd0a941Aa90A6e7aa97FB02F4" --partner-config "partner-shares.json" --gas-limit "200000" --network regtest
npx hardhat collector:change-partners --collector-address "0x9b91c655AaE10E6cd0a941Aa90A6e7aa97FB02F4" --partner-config "partner-shares.json" --gas-limit "200000" --network regtest
```

#### Add collector token
Expand Down Expand Up @@ -156,19 +156,21 @@ This file also is being exported on the distributable version to provide the con

Once the smart contracts are deployed, tokens must be individually allowed to be able to work with the RIF Relay system. In the same way, tokens can be removed from the list of previously allowed tokens. There are some helpful commands for this:

1. To allow a specific token, run `npx hardhat allow-tokens --network <NETWORK_NAME> <TOKEN_ADDRESSES>` where:
1. To allow a specific token, run `npx hardhat allow-tokens --network <NETWORK_NAME> --token-list <TOKEN_ADDRESSES>` where:
- `<TOKEN_ADDRESSES>` is a comma-separated list of the token addresses to be allowed on the available verifiers
- `<NETWORK_NAME>` is an optional parameter for the network name, taken from the `hardhat.config.ts` file (default value is `hardhat`) **important! This should be the same network name as the one used to deploy the contracts**
2. To query allowed tokens run `npx hardhat allowed-tokens --network <NETWORK_NAME>`. This will display them on the console.
3. To remove a sepecific token, run `npx hardhat remove-tokens --network <NETWORK_NAME> <TOKEN_ADDRESSES>` where:
If you want to modify just one or few verifiers, please specify it with the argument `--verifier-list` in a comma-separated format: `npx hardhat allow-tokens --network <NETWORK_NAME> --token-list <TOKEN_ADDRESSES> --verifier-list <address1,address2>`
2. To query allowed tokens run `npx hardhat allowed-tokens --network <NETWORK_NAME>`. This will display them on the console. If you want to query just one or few verifiers, please specify it with the argument `--verifier-list` in a comma-separated format: `npx hardhat allowed-tokens --network <NETWORK_NAME> --verifier-list <address1,address2>`
3. To remove a specific token, run `npx hardhat remove-tokens --network <NETWORK_NAME> --token-list <TOKEN_ADDRESSES>` where:
- `<TOKEN_ADDRESSES>` is a comma-separated list of the token addresses to be removed on the available verifiers.
- `<NETWORK_NAME>` is an optional parameter for the network name, taken from the `hardhat.config.ts` file (default value is `hardhat`) **important! This should be the same network name as the one used to deploy the contracts**.
If you want to modify just one or few verifiers, please specify it with the argument `--verifier-list` in a comma-separated format: `npx hardhat remove-tokens --network <NETWORK_NAME> --token-list <TOKEN_ADDRESSES> --verifier-list <address1,address2>`
franciscotobar marked this conversation as resolved.
Show resolved Hide resolved

### UtilToken Minting

Once the smart contracts are deployed, [UtilToken](./contracts/utils/UtilToken.sol)s can be minted and transferred by using the related script:
```bash
npx hardhat mint --token-address <0xabc123> --amount <amount_in_wei> --receiver <0xabc123> --network <network_name>
npx hardhat mint --token-address <0xabc123> --amount <amount_in_wei> --receiver <0xabc123> --network <NETWORK_NAME>
```
Parameters:
- `token-address`: the address of the token that will be minted. The ERC20 token that will be used, needs to have a mint function.
Expand Down
44 changes: 29 additions & 15 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'hardhat-watcher';
import { HardhatUserConfig, task } from 'hardhat/config';
import { HttpNetworkUserConfig } from 'hardhat/types';
import { mint, MintArgs } from './tasks/mint';
import { allowTokens } from './tasks/allowTokens';
import { AllowedTokensArgs, allowTokens } from './tasks/allowTokens';
import {
changePartnerShares,
ChangePartnerSharesArg,
Expand All @@ -17,7 +17,10 @@ import {
deployCollector,
DeployCollectorArg,
} from './tasks/collector/deployCollector';
import { getAllowedTokens } from './tasks/getAllowedTokens';
import {
GetAllowedTokensArgs,
getAllowedTokens,
} from './tasks/getAllowedTokens';
import { removeTokens } from './tasks/removeTokens';
import { withdraw, WithdrawSharesArg } from './tasks/withdraw';
import {
Expand Down Expand Up @@ -135,16 +138,33 @@ task('collector:deploy', 'Deploys the collector')
});

task('allow-tokens', 'Allows a list of tokens')
.addPositionalParam('tokenlist', 'list of tokens')
.setAction(async (taskArgs: { tokenlist: string }, hre) => {
.addParam('tokenList', 'list of tokens')
.addOptionalParam(
'verifierList',
'list of tokens in a comma-separated format (e.g.: "address1,address2")'
)
.setAction(async (taskArgs: AllowedTokensArgs, hre) => {
await allowTokens(taskArgs, hre);
});

task('allowed-tokens', 'Retrieves a list of allowed tokens').setAction(
async (_, hre) => {
await getAllowedTokens(hre);
}
);
task('allowed-tokens', 'Retrieves a list of allowed tokens')
.addOptionalParam(
'verifierList',
'list of tokens in a comma-separated format (e.g.: "address1,address2")'
)
.setAction(async (taskArgs: GetAllowedTokensArgs, hre) => {
await getAllowedTokens(taskArgs, hre);
});

task('remove-tokens', 'Removes a list of tokens')
.addParam('tokenList', 'list of tokens')
.addOptionalParam(
'verifierList',
'list of tokens in a comma-separated format (e.g.: "address1,address2")'
)
.setAction(async (taskArgs: AllowedTokensArgs, hre) => {
await removeTokens(taskArgs, hre);
});

task('collector:withdraw', 'Withdraws funds from a collector contract')
.addParam(
Expand Down Expand Up @@ -192,12 +212,6 @@ task(
await removeTokenFromCollector(taskArgs, hre);
});

task('remove-tokens', 'Removes a list of tokens')
.addPositionalParam('tokenlist', 'list of tokens')
.setAction(async (taskArgs: { tokenlist: string }, hre) => {
await removeTokens(taskArgs, hre);
});

task('collector:change-partners', 'Change collector partners')
.addParam('collectorAddress', 'address of the collector contract to modify')
.addParam(
Expand Down
38 changes: 13 additions & 25 deletions tasks/allowTokens.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,28 @@
import { ContractTransaction } from 'ethers';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { getVerifiers } from './utils';
import { GetAllowedTokensArgs } from './getAllowedTokens';
import { getVerifiersFromArgs, getVerifiersFromFile } from './utils';

export type AllowedTokensArgs = GetAllowedTokensArgs & {
tokenList: string;
};

export const allowTokens = async (
taskArgs: { tokenlist: string },
{ tokenList, verifierList }: AllowedTokensArgs,
hre: HardhatRuntimeEnvironment
) => {
const tokenAddresses = taskArgs.tokenlist.split(',');

const {
deployVerifier,
relayVerifier,
customDeployVerifier,
customRelayVerifier,
nativeHolderDeployVerifier,
nativeHolderRelayVerifier,
} = await getVerifiers(hre);
const tokenAddresses = tokenList.split(',');

const verifierMap: Map<
string,
{ acceptToken: (tokenAddress: string) => Promise<ContractTransaction> }
> = new Map();
verifierMap.set('deployVerifier', deployVerifier);
verifierMap.set('relayVerifier', relayVerifier);
verifierMap.set('customDeployVerifier', customDeployVerifier);
verifierMap.set('customRelayVerifier', customRelayVerifier);
verifierMap.set('nativeHolderDeployVerifier', nativeHolderDeployVerifier);
verifierMap.set('nativeHolderRelayVerifier', nativeHolderRelayVerifier);
const verifiers = verifierList
? await getVerifiersFromArgs(verifierList, hre)
: await getVerifiersFromFile(hre);

for (const tokenAddress of tokenAddresses) {
for (const [key, verifier] of verifierMap) {
for (const verifier of verifiers) {
try {
await verifier.acceptToken(tokenAddress);
} catch (error) {
console.error(
`Error adding token with address ${tokenAddress} to allowed tokens on ${key}`
`Error adding token with address ${tokenAddress} to allowed tokens on Verifier at ${verifier.address}`
);
throw error;
}
Expand Down
42 changes: 19 additions & 23 deletions tasks/getAllowedTokens.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { getVerifiers } from './utils';
import { getVerifiersFromArgs, getVerifiersFromFile } from './utils';

export const getAllowedTokens = async (hre: HardhatRuntimeEnvironment) => {
const {
deployVerifier,
relayVerifier,
customDeployVerifier,
customRelayVerifier,
nativeHolderDeployVerifier,
nativeHolderRelayVerifier,
} = await getVerifiers(hre);
export type GetAllowedTokensArgs = {
verifierList?: string;
};

const verifierMap: Map<
string,
{ getAcceptedTokens: () => Promise<string[]> }
> = new Map();
verifierMap.set('deployVerifier', deployVerifier);
verifierMap.set('relayVerifier', relayVerifier);
verifierMap.set('customDeployVerifier', customDeployVerifier);
verifierMap.set('customRelayVerifier', customRelayVerifier);
verifierMap.set('nativeHolderDeployVerifier', nativeHolderDeployVerifier);
verifierMap.set('nativeHolderRelayVerifier', nativeHolderRelayVerifier);
export const getAllowedTokens = async (
{ verifierList }: GetAllowedTokensArgs,
hre: HardhatRuntimeEnvironment
) => {
const verifiers = verifierList
? await getVerifiersFromArgs(verifierList, hre)
: await getVerifiersFromFile(hre);

for (const [key, verifier] of verifierMap) {
for (const verifier of verifiers) {
try {
const allowedTokens = await verifier.getAcceptedTokens();
console.log(key, allowedTokens);
console.log(
`Verifier: ${verifier.address}, allowedTokens `,
allowedTokens
);
} catch (error) {
console.error(`Error getting allowed tokens for ${key}`);
console.error(
`Error getting allowed tokens for verifier at ${verifier.address}`
);
throw error;
}
}
Expand Down
47 changes: 15 additions & 32 deletions tasks/removeTokens.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,33 @@
import { ContractTransaction } from 'ethers';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { getVerifiers } from './utils';
import { AllowedTokensArgs } from './allowTokens';
import { getVerifiersFromArgs, getVerifiersFromFile } from './utils';

export const removeTokens = async (
taskArgs: { tokenlist: string },
{ tokenList, verifierList }: AllowedTokensArgs,
hre: HardhatRuntimeEnvironment
) => {
const tokenAddresses = taskArgs.tokenlist.split(',');
const tokenAddresses = tokenList.split(',');

const {
deployVerifier,
relayVerifier,
customDeployVerifier,
customRelayVerifier,
nativeHolderDeployVerifier,
nativeHolderRelayVerifier,
} = await getVerifiers(hre);

const verifierMap: Map<
string,
{
removeToken: (
tokenAddress: string,
index: number
) => Promise<ContractTransaction>;
getAcceptedTokens: () => Promise<string[]>;
}
> = new Map();

verifierMap.set('deployVerifier', deployVerifier);
verifierMap.set('relayVerifier', relayVerifier);
verifierMap.set('customDeployVerifier', customDeployVerifier);
verifierMap.set('customRelayVerifier', customRelayVerifier);
verifierMap.set('nativeHolderDeployVerifier', nativeHolderDeployVerifier);
verifierMap.set('nativeHolderRelayVerifier', nativeHolderRelayVerifier);
const verifiers = verifierList
? await getVerifiersFromArgs(verifierList, hre)
: await getVerifiersFromFile(hre);

for (const tokenAddress of tokenAddresses) {
for (const [key, verifier] of verifierMap) {
for (const verifier of verifiers) {
try {
const index = (await verifier.getAcceptedTokens()).indexOf(
tokenAddress
);
if (index === -1) {
console.log(
`Token with address ${tokenAddress} is not accepted on Verifier at ${verifier.address}`
);
continue;
}
await verifier.removeToken(tokenAddress, index);
} catch (error) {
console.error(
`Error removing token with address ${tokenAddress} from allowed tokens on ${key}`
`Error removing token with address ${tokenAddress} from allowed tokens on Verifier at ${verifier.address}`
);
throw error;
}
Expand Down
36 changes: 36 additions & 0 deletions tasks/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from 'fs';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { AddressesConfig } from './deploy';
import { TokenHandler } from 'typechain-types';

// TODO: we may convert this function to return a promise
export const parseJsonFile = <T>(filePath: string) => {
Expand Down Expand Up @@ -124,3 +125,38 @@ export async function getVerifiers(hre: HardhatRuntimeEnvironment) {
nativeHolderRelayVerifier,
};
}

export const getVerifiersFromFile = async (hre: HardhatRuntimeEnvironment) => {
const {
deployVerifier,
relayVerifier,
customDeployVerifier,
customRelayVerifier,
nativeHolderDeployVerifier,
nativeHolderRelayVerifier,
} = await getVerifiers(hre);

return [
deployVerifier,
relayVerifier,
customDeployVerifier,
customRelayVerifier,
nativeHolderDeployVerifier,
nativeHolderRelayVerifier,
] as TokenHandler[];
};

export const getTokenHandlerFromAddress = async (
address: string,
{ ethers }: HardhatRuntimeEnvironment
): Promise<TokenHandler> => await ethers.getContractAt('TokenHandler', address);

export const getVerifiersFromArgs = async (
verifierList: string,
hre: HardhatRuntimeEnvironment
) =>
Promise.all(
verifierList
.split(',')
.map((address) => getTokenHandlerFromAddress(address, hre))
);
6 changes: 3 additions & 3 deletions test/tasks/allowTokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import fs from 'fs';
import * as hre from 'hardhat';
import { ethers } from 'hardhat';
import sinon from 'sinon';
import { allowTokens } from '../../tasks/allowTokens';
import { AllowedTokensArgs, allowTokens } from '../../tasks/allowTokens';
import { stubReadFileSync } from './utils';

use(chaiAsPromised);

describe('Allow Tokens Script', function () {
franciscotobar marked this conversation as resolved.
Show resolved Hide resolved
describe('allowTokens', function () {
const taskArgs = {
tokenlist: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7',
const taskArgs: AllowedTokensArgs = {
tokenList: '0x145845fd06c85B7EA1AA2d030E1a747B3d8d15D7',
};

beforeEach(function () {
Expand Down
6 changes: 3 additions & 3 deletions test/tasks/getAllowedTokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ describe('Get Allowed Tokens Script', function () {
sinon.restore();
});

it('should get several lists of allowed tokens succesfully', async function () {
it('should get several lists of allowed tokens successfully', async function () {
const stubContract = sinon.createStubInstance(Contract);
stubContract['getAcceptedTokens'] = () => undefined;
sinon.stub(ethers, 'getContractAt').resolves(stubContract);
await expect(getAllowedTokens(hre)).to.not.be.rejected;
await expect(getAllowedTokens({}, hre)).to.not.be.rejected;
});

it('should throw error and print it if error while getting allowed tokens', async function () {
Expand All @@ -35,7 +35,7 @@ describe('Get Allowed Tokens Script', function () {
throw new Error();
};
sinon.stub(ethers, 'getContractAt').resolves(stubContract);
await expect(getAllowedTokens(hre)).to.be.rejected;
await expect(getAllowedTokens({}, hre)).to.be.rejected;
});
});
});
Loading
Loading