# NEBRA <> Axelar
## Axelar Protocol Brief Description
- Axelar General Message Passing (GMP) is a cross-chain messaging system. It is secured by a multisig of staked signers.
- The core API for the Axelar's GMP system is given by:
```solidity
// Initiate a cross-chain contract call
function callContract(string calldata destinationChain, string calldata contractAddress, bytes calldata payload) external;
// Record approvals for a set of messages, signed off by Axelar verifiers
function approveMessages(Message[] calldata messages, Proof calldata proof) external;
// Validate a message approval, and mark it as used
function validateMessage(string calldata sourceChain, string calldata messageId, string calldata sourceAddress, bytes32 payloadHash) external returns (bool);
// Query if a message is approved
function isMessageApproved(string calldata sourceChain, string calldata messageId, string calldata sourceAddress, address contractAddress, bytes32 payloadHash) external view returns (bool);
// Query if a message has been executed
function isMessageExecuted(string calldata sourceChain, string calldata messageId) external view returns (bool);
// Rotate to a new set of Axelar verifiers, signed off by the current Axelar verifiers
function rotateSigners(WeightedSigners memory newSigners, Proof calldata proof) external;
// Called by relayer to execute payload for approved message
function execute(string calldata sourceChain, string calldata messageId, string calldata sourceAddress, bytes calldata payload) external;
```
- A source contract calls a destination contract on a different chain via the following flow:
- `callContract` function is called on source contract. This function call has the payload to be executed on the destination contract. A`CallContract` event is emitted, indicating there is a message to be signed.
- Signers in multisig pickup this and other `CallContract` events and sign a batch of associated messages.
- The resulting signature, along with the underlying batch of messages, is submitted to `approveMessages` function on the destination chain. `approveMessages` verifies the signature and marks the messages as approved.
- A relayer can then call `execute` for a signed message on the destination contract. This will execute the bytecode payload associated with the message. Inside this process, the destination contract will call `validateMessage` to check whether the message was approved, and if so, mark it as executed to prevent replay attacks.
- The entire flow (taken from [Axelar docs](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity/blob/v5.9.0/contracts/gateway/INTEGRATION.md)) is shown in the diagram below:

## How Axelar Wants to Use ZKPs/NEBRA
- Suppose a batch of messages was signed by `S` signers. Then, `approveMessages` consists of verifying `S` signatures on the destination chain.
- Axelar would like to know whether verifying the `S` signatures inside a ZKP is *cheaper* than verifying them directly.
## TODOs for NEBRA Team
- [ ] Benchmark the gas cost of Axelar's `approveMessages` function for $S \in \{1,2,...,100\}$.
- [ ] Write a circuit that does batch signature verification (and perhaps some other Axelar specific logic).
- [ ] Update Axelar's `approveMessages` function to use this circuit.
- [ ] Benchmark gas cost of this updated `approveMessages` function (which now uses ZKPs) for $S \in \{1,2,...,100\}$.
| S | gas cost now | gas cost (with zk) | gas cost (zk + UPA) | gas cost (zk + UPA offchain) |
| -------- | -------- | -------- | -------- |-----|
| 4 | | | | |
| 8||||
| 16 ||||
| 32||||