Adding a Protocol (Local Test Example)

Implementing a Local Testing Environment for a Protocol with Bridges and Tokens

it("Add protocol", async () => {
        // Example params
        const protocolParams: ExternalDeveloperHub.ProtocolParamsStruct = {
            msgBetAmount: ethers.parseUnits("1", 18),
            dataBetAmount: ethers.parseUnits("1", 18),
            msgBetFirstReward: ethers.parseUnits("2", 18),
            msgBetReward: ethers.parseUnits("1", 18),
            dataBetFirstReward: ethers.parseUnits("2", 18),
            dataBetReward: ethers.parseUnits("1", 18),
            consensusTargetRate: CONSENSUS_RATE,
        };
        await NGL.mint(externalDeveloper.getAddress(), ethers.parseUnits("1000000", 18));
        await NGL.mint(admin.getAddress(), ethers.parseUnits("10000000", 18));
        await NGL.connect(externalDeveloper).approve(staking.externalDeveloperHub.getAddress(), ethers.parseUnits("10000000", 18));

        // This operation is not called by external developer by default
        let tx = await staking.externalDeveloperHub.connect(admin).approveExternalDeveloper(externalDeveloper.getAddress());
        await tx.wait();

        await (
            await staking.externalDeveloperHub
                .connect(externalDeveloper)
                .registerProtocol(
                    PROTOCOL_ID,
                    await externalDeveloper.getAddress(),
                    ethers.parseUnits("450", 18),
                    ethers.parseUnits("900", 18),
                    100,
                    protocolParams,
                    bridgeTransmitters.map(x => x.getAddress()),
                )
        ).wait();


        await (
            await staking.externalDeveloperHub
                .connect(externalDeveloper)
                .deposit(PROTOCOL_ID, ethers.parseUnits("1000", 18))
        ).wait();
        await (await staking.roundManager.turnRound()).wait();


        let receipt = await (
            await staking.externalDeveloperHub
                .connect(externalDeveloper)
                .addAllowedProtocolAddress(PROTOCOL_ID, CHAIN_ID, padAddress(await bridgeRouter.getAddress()))
        ).wait();


        const info = await ccm.masterSmartContract.getProtocolInfo(PROTOCOL_ID);
        console.log(info)


        // INIT protocol on target chain
        let proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args
        let op: OperationLib.OperationDataStruct = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: 1,
            srcBlockNumber: 1,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: 0,
            destChainId: CHAIN_ID,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };


        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);
        const allowedProtocolInfo = await ccm.endPoint.allowedProtocolInfo(PROTOCOL_ID); 
        console.log(allowedProtocolInfo)


        // handle proposal handleAddAllowedProtocol
        await printProposalEvents(receipt);
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[16])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 2,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: 0,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };


        // calls handleAddAllowedProtocol on MasterSmartContract
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);


        // fetch addAllowedProtocolAddress propose from handleAddAllowedProtocol function
        // and send data to endPoint
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt.hash, ethers.ZeroHash],
            nonce: 0,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);


        // CHECK endPoint settings
        const protocolId = await ccm.endPoint.protocolAddressToProtocolId(bridgeRouter.getAddress());
        expect(PROTOCOL_ID).eq(protocolId);


        receipt = await (await staking.externalDeveloperHub.connect(externalDeveloper)
            .addAllowedProposerAddress(PROTOCOL_ID, CHAIN_ID, padAddress(await bridgeRouter.getAddress()))).wait()


        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: proposal.nonce,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);



        receipt = await (await staking.externalDeveloperHub.connect(externalDeveloper)
            .addAllowedProtocolAddress(PROTOCOL_ID, CHAIN_ID, padAddress(await NGL.getAddress()))).wait()
        printProposalEvents(receipt!)
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: proposal.nonce,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);


        // WNGL
        receipt = await (await staking.externalDeveloperHub.connect(externalDeveloper)
            .addAllowedProtocolAddress(PROTOCOL_ID, CHAIN_ID, padAddress(await WNGL.getAddress()))).wait()
        printProposalEvents(receipt!)
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: proposal.nonce,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);


        const bridgeAllowed = await ccm.endPoint.allowedProposers(PROTOCOL_ID, await bridgeRouter.getAddress());
        console.log("\nBridge allowed as proposer:", bridgeAllowed, "\n")


        receipt = await (await staking.externalDeveloperHub.connect(externalDeveloper)
            .addAllowedProposerAddress(PROTOCOL_ID, CHAIN_ID, padAddress(await NGL.getAddress()))).wait()
        printProposalEvents(receipt!)
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: proposal.nonce,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);


        const nglAllowed = await ccm.endPoint.allowedProposers(PROTOCOL_ID, NGL.getAddress());
        console.log("\nNGL allowed as proposer:", nglAllowed, "\n")


        receipt = await (await staking.externalDeveloperHub.connect(externalDeveloper)
            .addAllowedProposerAddress(PROTOCOL_ID, CHAIN_ID, padAddress(await WNGL.getAddress()))).wait()
        printProposalEvents(receipt!)
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: proposal.nonce,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);
        
        const wnglAllowed = await ccm.endPoint.allowedProposers(PROTOCOL_ID, NGL.getAddress());
        console.log("\nWNGL allowed as proposer:", wnglAllowed, "\n")


        // adding protocol executor (backend) address
        receipt = await (await staking.externalDeveloperHub.connect(externalDeveloper)
            .addExecutor(PROTOCOL_ID, CHAIN_ID, padAddress(await bridgeExecutor.getAddress()))).wait()
        printProposalEvents(receipt!)
        proposal = PROPOSAL_EVENT_INTERFACE.parseLog(receipt!.logs[0])!.args;
        op = {
            protocolId: govProtocolId,
            meta: proposal.meta,
            srcChainId: CHAIN_ID,
            srcBlockNumber: 3,
            srcOpTxId: [receipt!.hash, ethers.ZeroHash],
            nonce: proposal.nonce,
            destChainId: proposal.destChainId,
            protocolAddr: proposal.protocolAddress,
            functionSelector: proposal.functionSelector,
            params: proposal.params,
            reserved: proposal.reserved
        };
        receipt = await executeProposal(op, ccm, govTransmitters, watchers, govExecutor);
    });

Last updated