Skip to content

Commit

Permalink
feat: factory deployment + small refactoring (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
JordyRo1 authored Jan 22, 2025
1 parent 0eaa1c0 commit 3c418a4
Show file tree
Hide file tree
Showing 5 changed files with 332 additions and 10 deletions.
248 changes: 248 additions & 0 deletions scripts/configs/pragma_sepolia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
{
"contracts": {
"merkleroot_multisig_ism": {
"name": "merkleroot_multisig_ism",
"constructor": {
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"validators": {
"type": "Span<felt252>",
"value": [
"0x0000000000000000000000000000000000000000000000000000000000000002"
]
},
"threshold": {
"type": "u32",
"value": "1"
}
}
},
"protocol_fee": {
"name": "protocol_fee",
"constructor": {
"max_protocol_fee_low": {
"type": "u128",
"value": "1000000000000000000"
},
"max_protocol_fee_high": {
"type": "u128",
"value": "0"
},
"protocol_fee_low": {
"type": "u128",
"value": "10000000000000000"
},
"protocol_fee_high": {
"type": "u128",
"value": "0"
},
"beneficiary": {
"type": "ContractAddress",
"value": "$BENEFICIARY_ADDRESS"
},
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"token_address": {
"type": "ContractAddress",
"value": "0x049D36570D4e46f48e99674bd3fcc84644DdD6b96F7C741B1562B82f9e004dC7"
}
}
},
"merkle_tree_hook": {
"name": "merkle_tree_hook",
"constructor": {
"mailbox": {
"type": "ContractAddress",
"value": "$mailbox"
},
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
}
}
},
"noop_ism": {
"name": "noop_ism",
"constructor": {}
},
"hook": {
"name": "hook",
"constructor": {}
},
"pausable_ism": {
"name": "pausable_ism",
"constructor": {
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
}
}
},
"trusted_relayer_ism": {
"name": "trusted_relayer_ism",
"constructor": {
"mailbox": {
"type": "ContractAddress",
"value": "$mailbox"
},
"trusted_relayer": {
"type": "ContractAddress",
"value": "0x0000000000000000000000000000000000000000000000000000000000000001"
}
}
},
"mailbox": {
"name": "mailbox",
"constructor": {
"local_domain": {
"type": "u32",
"value": "6363709"
},
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"default_ism": {
"type": "ContractAddress",
"value": "$noop_ism"
},
"default_hook": {
"type": "ContractAddress",
"value": "$hook"
},
"required_hook": {
"type": "ContractAddress",
"value": "$hook"
}
}
},
"validator_announce": {
"name": "validator_announce",
"constructor": {
"mailbox": {
"type": "ContractAddress",
"value": "$mailbox"
},
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
}
}
},
"aggregation": {
"name": "aggregation",
"constructor": {
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"modules": {
"type": "Span<felt252>",
"value": [
"0x0000000000000000000000000000000000000000000000000000000000000002"
]
},
"threshold": {
"type": "u32",
"value": "1"
}
}
},
"messageid_multisig_ism": {
"name": "messageid_multisig_ism",
"constructor": {
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"validators": {
"type": "Span<felt252>",
"value": [
"0x0000000000000000000000000000000000000000000000000000000000000003"
]
},
"threshold": {
"type": "u32",
"value": "1"
}
}
},
"default_fallback_routing_ism": {
"name": "default_fallback_routing_ism",
"constructor": {
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"mailbox": {
"type": "ContractAddress",
"value": "$mailbox"
}
}
},
"domain_routing_ism": {
"name": "domain_routing_ism",
"constructor": {
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
}
}
},
"domain_routing_hook": {
"name": "domain_routing_hook",
"constructor": {
"mailbox": {
"type": "ContractAddress",
"value": "$mailbox"
},
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
},
"token_address": {
"type": "ContractAddress",
"value": "0x049D36570D4e46f48e99674bd3fcc84644DdD6b96F7C741B1562B82f9e004dC7"
}
}
},
"XERC20Factory": {
"name": "XERC20Factory",
"constructor": {
"xerc20_class_hash": {
"type": "ClassHash",
"value": "$XERC20_CLASS_HASH"
},
"lockbox_class_hash": {
"type": "ClassHash",
"value": "$LOCKBOX_CLASS_HASH"
},
"owner": {
"type": "ContractAddress",
"value": "$OWNER_ADDRESS"
}
}
}
},
"deploymentOrder": [
"merkleroot_multisig_ism",
"messageid_multisig_ism",
"domain_routing_ism",
"noop_ism",
"pausable_ism",
"aggregation",
"protocol_fee",
"hook",
"mailbox",
"merkle_tree_hook",
"default_fallback_routing_ism",
"trusted_relayer_ism",
"validator_announce",
"domain_routing_hook",
"XERC20Factory"
]
}
63 changes: 53 additions & 10 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dotenv.config();

const BUILD_PATH = "../cairo/target/dev/contracts";
const MOCK_BUILD_PATH = "../cairo/target/dev/mocks";
const TOKEN_BUILD_PATH= "../xerc20/target/dev/xerc20"
const ACCOUNT_ADDRESS = process.env.ACCOUNT_ADDRESS;
const CONFIGS_DIR = 'configs';
const DEPLOYMENTS_DIR = 'deployments';
Expand All @@ -38,7 +39,7 @@ function getConfigPath(network: string): string {
throw new Error('NETWORK environment variable is not set');
}

const configFileName = `${network.toLowerCase()}.json`;
const configFileName = `pragma_${network.toLowerCase()}.json`;
const configPath = path.join(CONFIGS_DIR, configFileName);

if (!fs.existsSync(configPath)) {
Expand Down Expand Up @@ -70,12 +71,15 @@ function ensureNetworkDirectory(network: string): string {
function findContractFile(name: string, suffix: string): string {
const mainPath = `${BUILD_PATH}_${name}${suffix}`;
const mockPath = `${MOCK_BUILD_PATH}_${name}${suffix}`;
const xerc20Path = `${TOKEN_BUILD_PATH}_${name}${suffix}`;

if (fs.existsSync(mainPath)) {
return mainPath;
} else if (fs.existsSync(mockPath)) {
console.log(`Using mock contract for ${name} from ${mockPath}`);
return mockPath;
} else if (fs.existsSync(xerc20Path)) {
return xerc20Path;
}

throw new Error(`Contract file not found for ${name} with suffix ${suffix} in either ${BUILD_PATH} or ${MOCK_BUILD_PATH}`);
Expand All @@ -93,26 +97,48 @@ function getCompiledContractCasm(name: string): any {
return json.parse(fs.readFileSync(contractPath).toString("ascii"));
}

function processConstructorArgs(args: Record<string, { type: string; value: string | string[] }>, deployedContracts: DeployedContracts): any {
return Object.entries(args).reduce((acc, [key, { type, value }]) => {
async function processConstructorArgs(
args: Record<string, { type: string; value: string | string[] }>,
deployedContracts: DeployedContracts,
account: Account
): Promise<any> {

if (!ACCOUNT_ADDRESS) {
throw new Error('ACCOUNT_ADDRESS environment variable is not set');
}

if (!process.env.BENEFICIARY_ADDRESS) {
throw new Error('BENEFICIARY_ADDRESS environment variable is not set');
}

const processedArgs: Record<string, string | string[]> = {};

for (const [key, { type, value }] of Object.entries(args)) {
if (typeof value === 'string' && value.startsWith('$')) {
if (value === '$OWNER_ADDRESS') {
acc[key] = ACCOUNT_ADDRESS;
processedArgs[key] = ACCOUNT_ADDRESS as string;
} else if (value === '$BENEFICIARY_ADDRESS') {
acc[key] = process.env.BENEFICIARY_ADDRESS;
processedArgs[key] = process.env.BENEFICIARY_ADDRESS as string;
} else if (value === '$XERC20_CLASS_HASH') {
const xerc20ClassHash = await declareContract(account, 'XERC20');
processedArgs[key] = xerc20ClassHash;
} else if (value === '$LOCKBOX_CLASS_HASH') {
const lockboxClassHash = await declareContract(account, 'XERC20Lockbox');
processedArgs[key] = lockboxClassHash;
} else {
const contractName = value.slice(1);
if (deployedContracts[contractName]) {
acc[key] = deployedContracts[contractName];
processedArgs[key] = deployedContracts[contractName];
} else {
throw new Error(`Contract ${contractName} not yet deployed, required for ${key}`);
}
}
} else {
acc[key] = value;
processedArgs[key] = value;
}
return acc;
}, {} as any);
}

return processedArgs;
}

async function deployContract(
Expand All @@ -125,7 +151,7 @@ async function deployContract(

const compiledContract = getCompiledContract(contractName);
const casm = getCompiledContractCasm(contractName);
const processedArgs = processConstructorArgs(constructorArgs, deployedContracts);
const processedArgs = await processConstructorArgs(constructorArgs, deployedContracts, account);
const constructorCalldata = CallData.compile(processedArgs);
const params: ContractFactoryParams = {
compiledContract,
Expand All @@ -141,6 +167,23 @@ async function deployContract(
return contract.address;
}


async function declareContract(account: Account, name: string): Promise<string> {
console.log(`Declaring contract ${name}...`);
const compiledContract = getCompiledContract(name);
const casm = getCompiledContractCasm(name);

const declareResponse = await account.declareIfNot({
contract: compiledContract,
casm
});

console.log(`Contract ${name} declared with class hash:`, declareResponse.class_hash);

return declareResponse.class_hash;
}


async function deployContracts(): Promise<DeployedContracts> {
try {
if (!NETWORK) {
Expand Down
15 changes: 15 additions & 0 deletions scripts/deployments/devnet/deployments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"merkleroot_multisig_ism": "0x0414ccc4c79a3a0baa38cb7fdc4936700b28880920fe83a5688517551b0c9a89",
"messageid_multisig_ism": "0x07fec6a00ceee11c34d8958260b97fc3ffe467ccb57f53a96fa29658f390c123",
"domain_routing_ism": "0x02f87d93f2c0d12edc6e012bc2e5cb7ee3926dfeac2263eac36d3a0dab20aeaa",
"noop_ism": "0x04debe0a6c1512efe772d66d5a783fe23446acd3fc0766b74cbba00b03617132",
"pausable_ism": "0x015049e37920b1512d08a851af968914faf57bef5b63658688a7b292f6cb1082",
"aggregation": "0x007d37fd4173a9ef2f26c1591c97303f0f12ac0af02149374e89fb889f8bf6fd",
"protocol_fee": "0x051a4ebcb1b9535e7a9b4a71ca6a503db42eb96d2437d4f965fba8f2b1a258ce",
"hook": "0x02b8a2308a4cb554eaa084f798691b6375664eb8b45f9be40e6bf64716ca68fc",
"mailbox": "0x064bb5e29a7e9fc67dedabb6d1c385050feef028563078daa9025dd8b218e596",
"merkle_tree_hook": "0x0536953cdd0dd5b8e24428e4fb6eab5c143daba15f62b24606e50d822508faef",
"default_fallback_routing_ism": "0x02826ac1066e1a3d557d5e86f5deb2656b874f7415bd72895a34bc5333b9a34d",
"trusted_relayer_ism": "0x06af263233c402ed2f0cf6c27ca0bb27ab858c39bc2ad8c59ae934d91fe89828",
"validator_announce": "0x049c1f9e4da6bd2c020cb45f4f4880c5b2a69a591587bb608acd6b2b0b5b2c74"
}
Loading

0 comments on commit 3c418a4

Please sign in to comment.