Skip to content

Commit

Permalink
feat: add option to set flow limit through its in multisig script [AX…
Browse files Browse the repository at this point in the history
…E-2678] (#120)

* add: util function to check passed value is bytes32 array

* add: option to set flow limit in its including offline signing

---------

Co-authored-by: Dean Amiel <[email protected]>
Co-authored-by: Dean <[email protected]>
  • Loading branch information
3 people authored Dec 13, 2023
1 parent e2a71e7 commit 62df416
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
61 changes: 60 additions & 1 deletion evm/multisig.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ const {
mainProcessor,
isValidDecimal,
prompt,
isBytes32Array,
getGasOptions,
} = require('./utils');
const { addBaseOptions } = require('./cli-utils');
const IMultisig = require('@axelar-network/axelar-gmp-sdk-solidity/interfaces/IMultisig.json');
const IGateway = require('@axelar-network/axelar-gmp-sdk-solidity/interfaces/IAxelarGateway.json');
const IGovernance = require('@axelar-network/axelar-gmp-sdk-solidity/interfaces/IAxelarServiceGovernance.json');
const IInterchainTokenService = require('@axelar-network/interchain-token-service/interfaces/IInterchainTokenService.json');
const ITokenManager = require('@axelar-network/interchain-token-service/interfaces/ITokenManager.json');
const IOperatable = require('@axelar-network/interchain-token-service/interfaces/IOperatable.json');
const { parseEther } = require('ethers/lib/utils');
const { getWallet, signTransaction, storeSignedTx } = require('./sign-utils');

Expand Down Expand Up @@ -82,6 +86,7 @@ async function processCommand(_, chain, options) {
address,
action,
symbols,
tokenIds,
limits,
mintLimiter,
recipient,
Expand Down Expand Up @@ -286,6 +291,57 @@ async function processCommand(_, chain, options) {
tx = await governanceContract.populateTransaction.executeMultisigProposal(target, calldata, nativeValue);
break;
}

case 'setFlowLimits': {
const tokenIdsArray = JSON.parse(tokenIds);
const limitsArray = JSON.parse(limits);

if (!isBytes32Array(tokenIdsArray)) {
throw new Error(`Invalid token symbols: ${tokenIds}`);
}

if (!isNumberArray(limitsArray)) {
throw new Error(`Invalid token limits: ${limits}`);
}

if (tokenIdsArray.length !== limitsArray.length) {
throw new Error('Token ids and token flow limits length mismatch');
}

const multisigTarget = chain.contracts.InterchainTokenService?.address;

if (!isValidAddress(multisigTarget)) {
throw new Error(`Missing InterchainTokenService address in the chain info.`);
}

const its = new Contract(multisigTarget, IInterchainTokenService.abi, wallet);
const multisigCalldata = its.interface.encodeFunctionData('setFlowLimits', [tokenIdsArray, limitsArray]);

printInfo('Token Ids', tokenIdsArray);
printInfo('FLow limit values', limitsArray);

if (!offline) {
await preExecutionChecks(multisigContract, action, wallet, multisigTarget, multisigCalldata, 0, yes);
const operatable = new Contract(multisigTarget, IOperatable.abi, wallet);
const hasOperatorRole = await operatable.isOperator(wallet.address);

if (!hasOperatorRole) {
throw new Error('Missing Operator role for the used wallet address.');
}

// loop over each token
for (let i = 0; i < tokenIdsArray.length; ++i) {
const tokenManagerAddress = await its.validTokenManagerAddress(tokenIdsArray[i]);
const tokenManager = new Contract(tokenManagerAddress, ITokenManager.abi, wallet);
const currentFlowLimit = await tokenManager.flowLimit(tokenIdsArray[i]);
printInfo(`TokenManager address`, tokenManagerAddress);
printInfo(`TokenManager current flowLimit`, currentFlowLimit);
}
}

tx = await multisigContract.populateTransaction.executeContract(multisigTarget, multisigCalldata, 0, gasOptions);
break;
}
}

const { baseTx, signedTx } = await signTransaction(wallet, chain, tx, options);
Expand Down Expand Up @@ -322,7 +378,7 @@ if (require.main === module) {
program.addOption(new Option('-c, --contractName <contractName>', 'contract name').default('Multisig').makeOptionMandatory(false));
program.addOption(
new Option('--action <action>', 'multisig action')
.choices(['signers', 'setTokenMintLimits', 'transferMintLimiter', 'withdraw', 'executeMultisigProposal'])
.choices(['signers', 'setTokenMintLimits', 'transferMintLimiter', 'withdraw', 'executeMultisigProposal', 'setFlowLimits'])
.makeOptionMandatory(true),
);
program.addOption(new Option('--offline', 'run script in offline mode'));
Expand All @@ -346,6 +402,9 @@ if (require.main === module) {
new Option('--nativeValue <nativeValue>', 'execute multisig proposal nativeValue').makeOptionMandatory(false).default(0),
);

// option for setFlowLimit in ITS
program.addOption(new Option('--tokenIds <tokenIds>', 'token ids'));

program.action((options) => {
main(options);
});
Expand Down
15 changes: 15 additions & 0 deletions evm/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,20 @@ const isAddressArray = (arr) => {
return true;
};

const isBytes32Array = (arr) => {
if (!Array.isArray(arr)) {
return false;
}

for (const item of arr) {
if (typeof item !== 'string' || !item.startsWith('0x') || item.length !== 66) {
return false;
}
}

return true;
};

const getCurrentTimeInSeconds = () => {
const now = new Date();
const currentTimeInSecs = Math.floor(now.getTime() / 1000);
Expand Down Expand Up @@ -1035,6 +1049,7 @@ module.exports = {
mainProcessor,
getContractPath,
getContractJSON,
isBytes32Array,
getGasOptions,
getSaltFromKey,
};

0 comments on commit 62df416

Please sign in to comment.