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