# UMA - IS_RELAY_VALID procedure

By [birchskin](https://paragraph.com/@patsaw) · 2021-12-09

---

This was buried in discord and not yet in the official UMA documentation, but I wanted an easily referenced document on this process / setup / prereqs. This is a technical guide on how to run validation on [IS\_RELAY\_VALID](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-136.md) requests in the UMA Protocol

You can read more about UMA Protocol [here](https://docs.umaproject.org/) and more specifics around the voting process [here](https://docs.umaproject.org/uma-tokenholders/uma-holders) \_ _\_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \__ \_ _\_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \__

### Dependencies:

These instructions are specific to OSX, and should work on \*nix systems. If you happen to be a Windows developer and would like me to add to this, please reach out

You will need the following:

*   Node v14+
    
*   yarn
    
*   XCode Command Line Tools (to support project dependencies)
    

### Setup

First, you’ll need to clone the UMA Protocol repository to your local environment.

`git clone git@github.com:UMAprotocol/protocol.git`

Then move into the cloned directory, install node packages: `yarn`

Next you will need to build the contracts using the quick build node script: `yarn qbuild`

### Configuration

dotenv is used for environment variables, in this example the following values should be added to `.env` in the project directory to specify the nodes to connect to, with each L2 listed as `NODE_URL_<chainID>` example using infura nodes:

    CUSTOM_NODE_URL=https://mainnet.infura.io/v3/<YOURPROJECTID>
    NODE_URL_42161=https://arbitrum-mainnet.infura.io/v3/<YOURPROJECTID>
    NODE_URL_10=https://optimism-mainnet.infura.io/v3/<YOURPROJECTID>
    

Alternatively, you can use public RPC URLs from the [rpc.info list](https://rpc.info/) (Less secure)

The script also uses the environment variable `PRICE_FEED_CONFIG` - it defaults to Arbitrum (`NODE_URL_42161`) but can be set to the appropriate node ID for the relay in question, for example optimism would require an env variable of:

    PRICE_FEED_CONFIG='{"l2NetId": 10}'
    

### Checking the disputed price request

**Initial Check:**

Once the project is set up, from the root of the `protocols` directory you will want to capture the `Proposal`, `Ancillary Data (raw hexstring)` and `Proposal Timestamp` from [vote.umaproject.org](https://vote.umaproject.org/) on the proposal in question, then run the `getHistoricalPrice.js` script with those details :

    HARDHAT_NETWORK=mainnet \
    node ./packages/scripts/src/local/getHistoricalPrice.js \
    --network mainnet \
    --identifier <Proposal, ex: IS_RELAY_VALID> \
    --time <UTC timestamp, ex: 1638976595>
    --ancillaryData <Ancillary Data (raw), ex: 0x72656c6179486173683a633562366430353036326230393730643239643661393565353065646436383336633036653465613931626338343432626365616166663933363339363562322c6f6f5265717565737465723a37333535656663363361653733316635383433383061393833383239326337303436633165343333>
    

Running this command with the example values above:

    HARDHAT_NETWORK=mainnet node ./packages/scripts/src/local/getHistoricalPrice.js --network mainnet --identifier IS_RELAY_VALID --time 1638976595 --ancillaryData 0x72656c6179486173683a633562366430353036326230393730643239643661393565353065646436383336633036653465613931626338343432626365616166663933363339363562322c6f6f5265717565737465723a37333535656663363361653733316635383433383061393833383239326337303436633165343333
    

This script will return **0** or **1**, for **NO**/**YES** on whether the relay is valid. In the example above, we received a **0** and should analyze the output:

**Data Validation:**

The first thing to do after getting the output from the above commands is to validate the output. Pretty-printing the JSON and going through the pertinent info:

The first 2 objects show the `InsuredBridgeL1Client` and `InsuredBridgeL2Client` - the data here shows me that the script is going to try to check chainId `42161` and `mainnet` (no chainId)

    {
        "at": "InsuredBridgeL2Client",
        "message": "Insured bridge l2 client updated",
        "chainId": 42161,
        "level": "debug"
    } {
        "at": "InsuredBridgeL1Client",
        "message": "Insured bridge l1 client updated",
        "level": "debug"
    } 
    

The next section will show the `matchedRelay` - where you can see the `relayData` object which has no `chainId` property, however the value at 0 of `1` tells us the relay is mainnet:

    {
        "at": "InsuredBridgePriceFeed",
        "message": "Matched relay",
        "matchedRelay": {
            "relayData": {
                "0": "1",
    .........
            },
    

and then, the `depositData` shows us the chainID is `10`

            "depositData": {
                "0": "10",
                   ......
                "chainId": "10",
                 ......
    

Notice that the chainId differs from the default of Arbitrum / `42161` and is actually Optimism / `10` - **this tells us that we need to change the** `l2NetId` in `PRICE_FEED_CONFIG` - within my `.env` file:

    PRICE_FEED_CONFIG='{"l2NetId": 10}'
    

Now running the command again:

    HARDHAT_NETWORK=mainnet node ./packages/scripts/src/local/getHistoricalPrice.js --network mainnet --identifier IS_RELAY_VALID --time 1635440180 --ancillaryData 0x72656c6179486173683a33643737356334356531626531353564636164626634646163383365346439343031666533313933623837386565353566633837383362656133346662333764
    

I get the following output:

    {
        "l2NetId": 10
    } {
        "at": "createReferencePriceFeedForFinancialContract",
        "message": "Inferred default config from identifier or Financial Contract address",
        "financialContractAddress": null,
        "identifier": "IS_RELAY_VALID",
        "defaultConfig": {
            "type": "insuredbridge",
            "l2BlockLookback": 99000,
            "l2NetId": 42161,
            "bridgeAdminAddress": "0x30B44C676A05F1264d1dE9cC31dB5F2A945186b6",
            "rateModels": {
                "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
                    "UBar": "650000000000000000",
                    "R0": "0",
                    "R1": "80000000000000000",
                    "R2": "1000000000000000000"
                },
                "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
                    "UBar": "800000000000000000",
                    "R0": "0",
                    "R1": "40000000000000000",
                    "R2": "600000000000000000"
                },
                "0x04fa0d235c4abf4bcf4787af4cf447de572ef828": {
                    "UBar": "500000000000000000",
                    "R0": "0",
                    "R1": "50000000000000000",
                    "R2": "2000000000000000000"
                },
                "0x3472A5A71965499acd81997a54BBA8D852C6E53d": {
                    "UBar": "500000000000000000",
                    "R0": "25000000000000000",
                    "R1": "25000000000000000",
                    "R2": "2000000000000000000"
                }
            },
            "priceFeedDecimals": 18
        },
        "level": "debug"
    } {
        "at": "createReferencePriceFeedForFinancialContract",
        "message": "Found both a default config and a user-config",
        "defaultConfig": {
            "type": "insuredbridge",
            "l2BlockLookback": 99000,
            "l2NetId": 42161,
            "bridgeAdminAddress": "0x30B44C676A05F1264d1dE9cC31dB5F2A945186b6",
            "rateModels": {
                "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
                    "UBar": "650000000000000000",
                    "R0": "0",
                    "R1": "80000000000000000",
                    "R2": "1000000000000000000"
                },
                "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
                    "UBar": "800000000000000000",
                    "R0": "0",
                    "R1": "40000000000000000",
                    "R2": "600000000000000000"
                },
                "0x04fa0d235c4abf4bcf4787af4cf447de572ef828": {
                    "UBar": "500000000000000000",
                    "R0": "0",
                    "R1": "50000000000000000",
                    "R2": "2000000000000000000"
                },
                "0x3472A5A71965499acd81997a54BBA8D852C6E53d": {
                    "UBar": "500000000000000000",
                    "R0": "25000000000000000",
                    "R1": "25000000000000000",
                    "R2": "2000000000000000000"
                }
            },
            "priceFeedDecimals": 18
        },
        "userConfig": {
            "lookback": 3630364,
            "priceFeedDecimals": 18,
            "l2NetId": 10
        },
        "combinedConfig": {
            "type": "insuredbridge",
            "l2BlockLookback": 99000,
            "l2NetId": 10,
            "bridgeAdminAddress": "0x30B44C676A05F1264d1dE9cC31dB5F2A945186b6",
            "rateModels": {
                "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
                    "UBar": "650000000000000000",
                    "R0": "0",
                    "R1": "80000000000000000",
                    "R2": "1000000000000000000"
                },
                "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
                    "UBar": "800000000000000000",
                    "R0": "0",
                    "R1": "40000000000000000",
                    "R2": "600000000000000000"
                },
                "0x04fa0d235c4abf4bcf4787af4cf447de572ef828": {
                    "UBar": "500000000000000000",
                    "R0": "0",
                    "R1": "50000000000000000",
                    "R2": "2000000000000000000"
                },
                "0x3472A5A71965499acd81997a54BBA8D852C6E53d": {
                    "UBar": "500000000000000000",
                    "R0": "25000000000000000",
                    "R1": "25000000000000000",
                    "R2": "2000000000000000000"
                }
            },
            "priceFeedDecimals": 18,
            "lookback": 3630364
        },
        "level": "debug"
    } {
        "at": "createPriceFeed",
        "message": "Creating InsuredBridgePriceFeed",
        "config": {
            "type": "insuredbridge",
            "l2BlockLookback": 99000,
            "l2NetId": 10,
            "bridgeAdminAddress": "0x30B44C676A05F1264d1dE9cC31dB5F2A945186b6",
            "rateModels": {
                "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
                    "UBar": "650000000000000000",
                    "R0": "0",
                    "R1": "80000000000000000",
                    "R2": "1000000000000000000"
                },
                "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
                    "UBar": "800000000000000000",
                    "R0": "0",
                    "R1": "40000000000000000",
                    "R2": "600000000000000000"
                },
                "0x04fa0d235c4abf4bcf4787af4cf447de572ef828": {
                    "UBar": "500000000000000000",
                    "R0": "0",
                    "R1": "50000000000000000",
                    "R2": "2000000000000000000"
                },
                "0x3472A5A71965499acd81997a54BBA8D852C6E53d": {
                    "UBar": "500000000000000000",
                    "R0": "25000000000000000",
                    "R1": "25000000000000000",
                    "R2": "2000000000000000000"
                }
            },
            "priceFeedDecimals": 18,
            "lookback": 3630364
        },
        "level": "debug"
    } {
        "at": "InsuredBridgeL2Client",
        "message": "Insured bridge l2 client updated",
        "chainId": 10,
        "level": "debug"
    } {
        "at": "InsuredBridgeL1Client",
        "message": "Insured bridge l1 client updated",
        "level": "debug"
    } {
        "at": "InsuredBridgePriceFeed",
        "message": "No relay event found matching provided ancillary data. Has the relay been finalized already?",
        "level": "debug"
    }
    
    ⚠️ Truncating price to 18 decimals (default: 18)
    
    💹 Median IS_RELAY_VALID price @ 1635440180 = 0
    

Which confirms that I should vote `0` / `NO` on this IS\_RELAY\_VALID request

**Process/Script Details:**

The `getHistoricalPrice.js` script mimics how the relayer bot works, but utilizes the ancillary data, which the relayer bot does not use at all.

*   First, the script tries to find a matching `DepositRelayed` event across all BridgePools, matching the event’s `relayAncillaryDataHash` field with the parsed ancillaryData from the `SkinnyOptimisticOracle` event. We use the handy parseAncillaryData library to deconstruct the ancillary data into a relayHash
    
*   If the relay is found, next we need to find a `FundsDeposited` where the depositHash matches the deposit hash in the matched relay from the previous step. **Note that this step can fail if you’re connecting to an unexpected L2. For example, setting your node to Optimism but the deposit actually occurred on Arbitrum**
    
*   Finally, if the relay and the deposit is found, we just need to validate the relay params. There is only one param to validate: the `realizedLpFeePct`, so we use the same library that the bot and the front-end use to compute this and compare the relay’s fee set with the expected value for the deposit.quoteTime.

---

*Originally published on [birchskin](https://paragraph.com/@patsaw/uma-is-relay-valid-procedure)*
