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

feat(sui)!: add script option to pause sui contracts #519

Merged
merged 90 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
cc0f516
added a script to migrate tokens and moved custom token manager deplo…
Foivos Jan 17, 2025
7ac4625
made lint happy
Foivos Jan 17, 2025
a858b1b
prettier
Foivos Jan 17, 2025
0410347
addressed some comments
Foivos Jan 17, 2025
76946d0
Merge branch 'main' into feat/update-its-scripts
milapsheth Jan 20, 2025
23af473
remove callContractWithInterchainToken
Foivos Jan 20, 2025
4a9a73a
Update evm/its.js
Foivos Jan 20, 2025
744ff63
Merge remote-tracking branch 'origin/main' into feat/update-its-scripts
Foivos Jan 20, 2025
44fff22
add a test for register custom token
Foivos Jan 20, 2025
fbab1c3
try fixing the test
Foivos Jan 20, 2025
aa134ea
install latest its
Foivos Jan 20, 2025
39ec04a
fix deploy remote interchain token
Foivos Jan 20, 2025
1a6fdac
fix a bug
Foivos Jan 20, 2025
db64b2e
add deployRemoteInterchainToken back to the list
Foivos Jan 20, 2025
a5823f5
debug
Foivos Jan 20, 2025
da62165
fix a check
Foivos Jan 20, 2025
855b4dd
prettier
Foivos Jan 20, 2025
5334c58
add flow limit setter/getter
Foivos Jan 20, 2025
d883c84
fix spelling
Foivos Jan 20, 2025
62c6c23
properly handle event
Foivos Jan 20, 2025
d3127cc
stash
Foivos Jan 24, 2025
3d6ea08
Merge remote-tracking branch 'origin/main' into feat/sui-pause
Foivos Jan 24, 2025
f01faa0
Merge branch 'feat/update-its-scripts' into feat/sui-pause
Foivos Jan 24, 2025
30b30b1
update naming, cgp-sui package version should be uptdated after release
Foivos Jan 27, 2025
1e7e97e
Merge remote-tracking branch 'origin/main' into feat/update-its-naming
Foivos Jan 28, 2025
c6a359f
prettier
Foivos Jan 28, 2025
d046a49
hopefully fix tests
Foivos Jan 28, 2025
e512ebf
Merge branch 'feat/update-its-naming' into feat/sui-pause
Foivos Jan 28, 2025
943ca5d
prettier
Foivos Jan 28, 2025
305cec6
remove info file
Foivos Jan 28, 2025
efc7ebd
fix sui test
Foivos Jan 28, 2025
375e068
fix sui test
Foivos Jan 28, 2025
030229a
rename ITS to InterchainTokenService in its-example as well
Foivos Jan 28, 2025
d8a6c2a
some more renaming
Foivos Jan 28, 2025
282d92d
some more renaming again
Foivos Jan 28, 2025
c511953
some renaming went wrong
Foivos Jan 28, 2025
e7c5ec5
prettier
Foivos Jan 28, 2025
89b8547
rename in its.js as well
Foivos Jan 28, 2025
a3e3a50
fix trusted addresses
Foivos Jan 28, 2025
757e6e8
prettier
Foivos Jan 28, 2025
434424b
fix its-example some
Foivos Jan 28, 2025
d074ca1
testing error fails
Foivos Jan 28, 2025
5146813
some more renaming
Foivos Jan 28, 2025
8015250
fixed some tests
Foivos Jan 28, 2025
43789a3
fix source address
Foivos Jan 28, 2025
8047bd0
try more fixes
Foivos Jan 28, 2025
fb26303
try to fix test.yaml again
Foivos Jan 28, 2025
11f69b0
more fixing
Foivos Jan 28, 2025
8a0b1e5
Merge branch 'feat/update-its-naming' into feat/sui-pause
Foivos Jan 28, 2025
7a641be
fix pausing a bit
Foivos Jan 28, 2025
637fa98
Merge branch 'main' into feat/update-its-naming
milapsheth Jan 29, 2025
25d37a7
rename all ITS to InterchainTokenService
Foivos Jan 29, 2025
17de80a
use variables for hub chain name and address
Foivos Jan 29, 2025
3495196
addressed some comments
Foivos Jan 29, 2025
02cfc16
Merge remote-tracking branch 'origin/main' into feat/update-its-naming
Foivos Jan 29, 2025
38e807e
update test-sui
Foivos Jan 29, 2025
ec915aa
update its.js
Foivos Jan 29, 2025
cb76ff4
rename ITS to InterchainTokenSercvice everywhere
Foivos Jan 29, 2025
be6c9e7
prettier
Foivos Jan 29, 2025
2cfbcdf
Merge branch 'feat/update-its-naming' into feat/sui-pause
Foivos Jan 29, 2025
2d1e7f6
fix deploy script
Foivos Jan 29, 2025
42255fd
revert evm changes
Foivos Jan 29, 2025
9c0d83b
fix local.json test
Foivos Jan 29, 2025
235384c
remove trusted address tracking on info
Foivos Jan 29, 2025
82dc686
Merge branch 'feat/update-its-naming' into feat/sui-pause
Foivos Jan 29, 2025
d281992
some comments
Foivos Jan 29, 2025
3af6734
made lint happy
Foivos Jan 29, 2025
5de573e
added a separate script to pause
Foivos Jan 30, 2025
18fb63c
added its as as pausable
Foivos Jan 30, 2025
0e64c48
revernt interchainTokenFactory changes
Foivos Jan 30, 2025
d653c4c
add tests
Foivos Jan 31, 2025
16638c3
some refactoring
Foivos Feb 4, 2025
96368d0
using most recent version
Foivos Feb 4, 2025
721c65b
stash
Foivos Feb 5, 2025
c5d8b4e
added a version option
Foivos Feb 5, 2025
8d3bf31
prettier
Foivos Feb 5, 2025
52eb9df
Merge remote-tracking branch 'origin/main' into feat/sui-pause
Foivos Feb 5, 2025
9ae1275
removed pause and unpause from gateway and its
Foivos Feb 5, 2025
02e8519
Merge remote-tracking branch 'origin/main' into feat/sui-pause
Foivos Feb 5, 2025
8c5e846
lint
Foivos Feb 6, 2025
9367476
Merge remote-tracking branch 'origin/main' into feat/sui-pause
Foivos Feb 6, 2025
5d69f40
update package-json
Foivos Feb 6, 2025
9ef0f56
fix sui tests
Foivos Feb 6, 2025
dc1448c
austoexecute pause/unpause in sui-tests
Foivos Feb 6, 2025
b232974
prettier
Foivos Feb 6, 2025
503d076
Merge branch 'main' into feat/sui-pause
milapsheth Feb 6, 2025
7d7a17f
Update .github/workflows/test-sui.yaml
Foivos Feb 6, 2025
03d8197
addressed some comments
Foivos Feb 6, 2025
604f6ca
Update sui/contract.js
milapsheth Feb 7, 2025
0243f56
Merge branch 'main' into feat/sui-pause
milapsheth Feb 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .github/workflows/test-sui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ jobs:
run: node sui/gas-service.js collectGas --amount 0.1

###### Command: Gateway ######
- name: Gateway Pause
run: node sui/contract.js pause AxelarGateway -y

- name: Gateway Unpause
run: node sui/contract.js unpause AxelarGateway -y

milapsheth marked this conversation as resolved.
Show resolved Hide resolved
- name: Gateway Pause All
run: node sui/contract.js pause AxelarGateway --functions all -y

- name: Gateway Unpause
run: node sui/contract.js unpause AxelarGateway -y

- name: Gateway Approve
run: node sui/gateway.js approve --proof wallet ethereum 0x32034b47cb29d162d9d803cc405356f4ac0ec07fe847ace431385fe8acf3e6e5-2 0x4F4495243837681061C4743b74B3eEdf548D56A5 0x6ce0d81b412abca2770eddb1549c9fcff721889c3aab1203dc93866db22ecc4b 0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432

Expand All @@ -190,8 +202,20 @@ jobs:
node sui/gateway.js approve --proof wallet ethereum 0x32034b47cb29d162d9d803cc405356f4ac0ec07fe847ace431385fe8acf3e6e5-3 0x4F4495243837681061C4743b74B3eEdf548D56A5 $channel_id 0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432
node sui/gmp.js execute ethereum 0x32034b47cb29d162d9d803cc405356f4ac0ec07fe847ace431385fe8acf3e6e5-3 0x4F4495243837681061C4743b74B3eEdf548D56A5 0x1234

###### Command: ITS Example ######
###### Command: ITS ######
- name: ITS Pause
run: node sui/contract.js pause InterchainTokenService -y

- name: ITS Unpause
run: node sui/contract.js unpause InterchainTokenService -y

- name: ITS Pause
run: node sui/contract.js pause InterchainTokenService --functions all -y

- name: ITS Unpause
run: node sui/contract.js unpause InterchainTokenService -y

###### Command: ITS Example ######
- name: Prepare ITS Example Parameters
run: |
echo "sourceChain=Ethereum" >> $GITHUB_ENV
Expand Down
260 changes: 260 additions & 0 deletions sui/contract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
const { Command, Option } = require('commander');
const { TxBuilder } = require('@axelar-network/axelar-cgp-sui');
const { loadConfig, saveConfig, getChainConfig, printInfo } = require('../common/utils');
const {
addBaseOptions,
addOptionsToCommands,
getWallet,
printWalletInfo,
broadcastFromTxBuilder,
getAllowedFunctions,
} = require('./utils');

const SPECIAL_PAUSE_FUNCTION_TAGS = {
ALL: 'all', // All EVM chains that have InterchainTokenService deployed
DEFAULT: 'default',
};

const SPECIAL_UNPAUSE_FUNCTION_TAGS = {
DISALLOWED: 'disallowed', // All EVM chains that have InterchainTokenService deployed
DEFAULT: 'default',
};

const CONTRACT_INFO = {
AxelarGateway: {
singletonName: 'Gateway',
moduleName: 'gateway',
defaultFunctions: {
versions: [0, 0],
functionNames: ['approve_messages', 'rotate_signers'],
},
},
InterchainTokenService: {
singletonName: 'InterchainTokenService',
moduleName: 'interchain_token_service',
defaultFunctions: {
versions: [0, 0, 0, 0, 0, 0, 0, 0, 0],
functionNames: [
'register_coin',
'deploy_remote_interchain_token',
'send_interchain_transfer',
'receive_interchain_transfer',
'receive_interchain_transfer_with_data',
'receive_deploy_interchain_token',
'mint_as_distributor',
'mint_to_as_distributor',
'burn_as_distributor',
],
},
},
};

function getVariablesForPackage(chain, packageName) {
const contractConfig = chain.contracts[packageName];
const info = CONTRACT_INFO[packageName];
const defaultFunctions = info.defaultFunctions;
const version = Math.max(...Object.keys(contractConfig.versions).map((version) => Number(version)));
defaultFunctions.versions.fill(version);
return {
packageId: contractConfig.address,
singletonId: contractConfig.objects[info.singletonName],
versionedId: contractConfig.objects[info.singletonName + 'v0'],
ownerCapId: contractConfig.objects.OwnerCap,
moduleName: info.moduleName,
defaultFunctions: info.defaultFunctions,
contract: contractConfig,
};
}

async function allowFunctions(keypair, client, packageId, moduleName, singletonId, ownerCapId, versions, functionNames, options) {
if (versions.length !== functionNames.length) throw new Error('Versions and Function Names must have a matching length');

const builder = new TxBuilder(client);

for (const i in versions) {
await builder.moveCall({
target: `${packageId}::${moduleName}::allow_function`,
arguments: [singletonId, ownerCapId, versions[i], functionNames[i]],
});
}

await broadcastFromTxBuilder(builder, keypair, 'Allow Functions', options);
}

async function disallowFunctions(keypair, client, packageId, moduleName, singletonId, ownerCapId, versions, functionNames, options) {
if (versions.length !== functionNames.length) throw new Error('Versions and Function Names must have a matching length');

const builder = new TxBuilder(client);

for (const i in versions) {
await builder.moveCall({
target: `${packageId}::${moduleName}::disallow_function`,
arguments: [singletonId, ownerCapId, versions[i], functionNames[i]],
});
}

await broadcastFromTxBuilder(builder, keypair, 'Disallow Functions', options);
}

async function pause(keypair, client, chain, args, options) {
const [packageName] = args;
const functions = options.functions;

const { packageId, singletonId, versionedId, ownerCapId, moduleName, defaultFunctions, contract } = getVariablesForPackage(
chain,
packageName,
);

let versionsArg = [];
let allowedFunctionsArg = [];

if (functions === SPECIAL_PAUSE_FUNCTION_TAGS.ALL) {
const allowedFunctionsArray = await getAllowedFunctions(client, versionedId);

for (const version in allowedFunctionsArray) {
if (options.version !== 'all' && options.version !== version) {
continue;
}

let allowedFunctions = allowedFunctionsArray[version];

// Do not dissalow `allow_function` because that locks the gateway forever.
if (Number(version) === allowedFunctionsArray.length - 1) {
allowedFunctions = allowedFunctions.filter(
(allowedFunction) => allowedFunction !== 'allow_function' && allowedFunction !== 'disallow_function',
);
}

printInfo(`Functions that will be disallowed for version ${version}`, allowedFunctions);

versionsArg = versionsArg.concat(new Array(allowedFunctions.length).fill(Number(version)));
allowedFunctionsArg = allowedFunctionsArg.concat(allowedFunctions);
}
} else if (functions === SPECIAL_PAUSE_FUNCTION_TAGS.DEFAULT) {
versionsArg = defaultFunctions.versions;
allowedFunctionsArg = defaultFunctions.functionNames;
} else if (options.version !== 'all') {
allowedFunctionsArg = functions.split(',');
versionsArg = allowedFunctionsArg.map(() => Number(options.version));
} else {
throw new Error('Need to specify a version if providing specific functions.');
}

if (!contract.disallowedFunctions) {
contract.disallowedFunctions = {
versions: [],
functionNames: [],
};
}

contract.disallowedFunctions.versions = contract.disallowedFunctions.versions.concat(versionsArg);
contract.disallowedFunctions.functionNames = contract.disallowedFunctions.functionNames.concat(allowedFunctionsArg);

return await disallowFunctions(
keypair,
client,
packageId,
moduleName,
singletonId,
ownerCapId,
versionsArg,
allowedFunctionsArg,
options,
);
}

async function unpause(keypair, client, chain, args, options) {
const [packageName] = args;
const functions = options.functions;
const { packageId, singletonId, ownerCapId, moduleName, defaultFunctions, contract } = getVariablesForPackage(chain, packageName);

let versionsArg = [];
let allowedFunctionsArg = [];

if (functions === SPECIAL_UNPAUSE_FUNCTION_TAGS.DISALLOWED) {
versionsArg = contract.disallowedFunctions.versions.slice();
allowedFunctionsArg = contract.disallowedFunctions.functionNames.slice();
} else if (functions === SPECIAL_UNPAUSE_FUNCTION_TAGS.DEFAULT) {
versionsArg = defaultFunctions.versions;
allowedFunctionsArg = defaultFunctions.functionNames;
} else if (options.version !== 'all') {
allowedFunctionsArg = functions.split(',');
versionsArg = allowedFunctionsArg.map(() => Number(options.version));
} else {
throw new Error('Need to specify a version if providing specific functions.');
}

if (contract.disallowedFunctions) {
for (let i = contract.disallowedFunctions.versions.length - 1; i >= 0; i--) {
const version = contract.disallowedFunctions.versions[i];
const functionName = contract.disallowedFunctions.functionNames[i];

for (let j = 0; j < versionsArg.length; j++) {
if (version === versionsArg[j] && functionName === allowedFunctionsArg[j]) {
contract.disallowedFunctions.versions.splice(i, 1);
contract.disallowedFunctions.functionNames.splice(i, 1);
break;
}
}
}
}

return await allowFunctions(keypair, client, packageId, moduleName, singletonId, ownerCapId, versionsArg, allowedFunctionsArg, options);
}

async function processCommand(command, chain, args, options) {
const [keypair, client] = getWallet(chain, options);

await printWalletInfo(keypair, client, chain, options);

await command(keypair, client, chain, args, options);
}

async function mainProcessor(command, options, args, processor) {
const config = loadConfig(options.env);
const chain = getChainConfig(config, options.chainName);
await processor(command, chain, args, options);
saveConfig(config, options.env);
}

if (require.main === module) {
const program = new Command();
program.name('Pause').description('SUI Pause scripts');

const pauseProgram = new Command()
.name('pause')
.description('Pause')
.command('pause <package>')
.addOption(
new Option(
'--functions <functions>',
'The functions to allow. Use use "default" for the default functions, "all" for all functions except the most recent "allow_function" and a comma separated list for custom pausing.',
).default('default'),
)
.addOption(new Option('--version, <version>', 'The version to pause. Use all to pause all versions').default('all'))
.action((packageName, options) => {
mainProcessor(pause, options, [packageName], processCommand);
});

const unpauseProgram = new Command()
.name('unpause')
.description('Unpause')
.command('unpause <package>')
.addOption(
new Option(
'--functions, <functions>',
'The functions to pause. Use "disallowed" for previously disallowed functions, "default" for the default functions and a comma separated list for custom pausing.',
).default('disallowed'),
)
.addOption(new Option('--version, <version>', 'The version to pause. Use all to pause all versions').default('all'))
.action((packageName, options) => {
mainProcessor(unpause, options, [packageName], processCommand);
});

program.addCommand(pauseProgram);
program.addCommand(unpauseProgram);

addOptionsToCommands(program, addBaseOptions, { offline: true });

program.parse();
}
76 changes: 0 additions & 76 deletions sui/gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,68 +282,6 @@ async function rotate(keypair, client, config, chain, contractConfig, args, opti
};
}

async function allowFunctions(keypair, client, config, chain, contractConfig, args, options) {
const packageId = contractConfig.address;

const [versionsArg, functionNamesArg] = args;

const versions = versionsArg.split(',');
const functionNames = functionNamesArg.split(',');

if (versions.length !== functionNames.length) throw new Error('Versions and Function Names must have a matching length');

const tx = new Transaction();
console.log(contractConfig.objects);

for (const i in versions) {
tx.moveCall({
target: `${packageId}::gateway::allow_function`,
arguments: [
tx.object(contractConfig.objects.Gateway),
tx.object(contractConfig.objects.OwnerCap),
tx.pure.u64(versions[i]),
tx.pure.string(functionNames[i]),
],
});
}

return {
tx,
message: 'Allow Functions',
};
}

async function disallowFunctions(keypair, client, config, chain, contractConfig, args, options) {
const packageId = contractConfig.address;

const [versionsArg, functionNamesArg] = args;

const versions = versionsArg.split(',');
const functionNames = functionNamesArg.split(',');

if (versions.length !== functionNames.length) throw new Error('Versions and Function Names must have a matching length');

const tx = new Transaction();
console.log(contractConfig.objects);

for (const i in versions) {
tx.moveCall({
target: `${packageId}::gateway::disallow_function`,
arguments: [
tx.object(contractConfig.objects.Gateway),
tx.object(contractConfig.objects.OwnerCap),
tx.pure.u64(versions[i]),
tx.pure.string(functionNames[i]),
],
});
}

return {
tx,
message: 'Disallow Functions',
};
}

async function checkVersionControl(version, options) {
const config = loadConfig(options.env);

Expand Down Expand Up @@ -582,20 +520,6 @@ if (require.main === module) {
mainProcessor(callContract, [destinationChain, destinationAddress, payload], options);
});

program
.command('allow-functions <versions> <functionNames>')
.description('Allow certain funcitons on the gateway')
.action((versions, functionNames, options) => {
mainProcessor(allowFunctions, [versions, functionNames], options);
});

program
.command('disallow-functions <versions> <functionNames>')
.description('Allow certain funcitons on the gateway')
.action((versions, functionNames, options) => {
mainProcessor(disallowFunctions, [versions, functionNames], options);
});

program
.command('check-version-control <version>')
.description('Check if version control works on a certain version')
Expand Down
Loading