{
  "address": "0xCe2a0EC283be5AB085F57f4d398E0922BE0F7254",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "contract IController",
          "name": "_controller",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256[]",
          "name": "versions",
          "type": "uint256[]"
        }
      ],
      "name": "atVersions",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "version",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "timestamp",
              "type": "uint256"
            },
            {
              "internalType": "Fixed18",
              "name": "price",
              "type": "int256"
            }
          ],
          "internalType": "struct IOracleProvider.OracleVersion[]",
          "name": "prices",
          "type": "tuple[]"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "collateral",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "collateral",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "collateral",
      "outputs": [
        {
          "internalType": "contract ICollateral",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "controller",
      "outputs": [
        {
          "internalType": "contract IController",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "dailyRate",
      "outputs": [
        {
          "internalType": "Fixed18",
          "name": "",
          "type": "int256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "exposure",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "fees",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "fees",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "protocolFees",
          "type": "uint256"
        },
        {
          "internalType": "UFixed18",
          "name": "productFees",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "globalPosition",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "oracleVersion",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openPosition",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "closePosition",
              "type": "tuple"
            }
          ],
          "internalType": "struct PrePosition",
          "name": "",
          "type": "tuple"
        },
        {
          "components": [
            {
              "internalType": "UFixed18",
              "name": "maker",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "taker",
              "type": "uint256"
            }
          ],
          "internalType": "struct Position",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "info",
      "outputs": [
        {
          "components": [
            {
              "internalType": "string",
              "name": "name",
              "type": "string"
            },
            {
              "internalType": "string",
              "name": "symbol",
              "type": "string"
            },
            {
              "components": [
                {
                  "internalType": "enum PayoffDefinitionLib.PayoffType",
                  "name": "payoffType",
                  "type": "uint8"
                },
                {
                  "internalType": "enum PayoffDefinitionLib.PayoffDirection",
                  "name": "payoffDirection",
                  "type": "uint8"
                },
                {
                  "internalType": "bytes30",
                  "name": "data",
                  "type": "bytes30"
                }
              ],
              "internalType": "struct PayoffDefinition",
              "name": "payoffDefinition",
              "type": "tuple"
            },
            {
              "internalType": "contract IOracleProvider",
              "name": "oracle",
              "type": "address"
            },
            {
              "internalType": "UFixed18",
              "name": "maintenance",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "fundingFee",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "makerFee",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "takerFee",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "makerLimit",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "PackedFixed18",
                  "name": "minRate",
                  "type": "int128"
                },
                {
                  "internalType": "PackedFixed18",
                  "name": "maxRate",
                  "type": "int128"
                },
                {
                  "internalType": "PackedFixed18",
                  "name": "targetRate",
                  "type": "int128"
                },
                {
                  "internalType": "PackedUFixed18",
                  "name": "targetUtilization",
                  "type": "uint128"
                }
              ],
              "internalType": "struct JumpRateUtilizationCurve",
              "name": "utilizationCurve",
              "type": "tuple"
            }
          ],
          "internalType": "struct IProduct.ProductInfo",
          "name": "_info",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "latestVersion",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "version",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "timestamp",
              "type": "uint256"
            },
            {
              "internalType": "Fixed18",
              "name": "price",
              "type": "int256"
            }
          ],
          "internalType": "struct IOracleProvider.OracleVersion",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "liquidatable",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "liquidating",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "maintenance",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "UFixed18",
          "name": "positionSize",
          "type": "uint256"
        }
      ],
      "name": "maintenanceRequired",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "name",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "openInterest",
      "outputs": [
        {
          "components": [
            {
              "internalType": "UFixed18",
              "name": "maker",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "taker",
              "type": "uint256"
            }
          ],
          "internalType": "struct Position",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "openInterest",
      "outputs": [
        {
          "components": [
            {
              "internalType": "UFixed18",
              "name": "maker",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "taker",
              "type": "uint256"
            }
          ],
          "internalType": "struct Position",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "position",
      "outputs": [
        {
          "components": [
            {
              "internalType": "UFixed18",
              "name": "maker",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "taker",
              "type": "uint256"
            }
          ],
          "internalType": "struct Position",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "position",
      "outputs": [
        {
          "components": [
            {
              "internalType": "UFixed18",
              "name": "maker",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "taker",
              "type": "uint256"
            }
          ],
          "internalType": "struct Position",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "pre",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "oracleVersion",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openPosition",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "closePosition",
              "type": "tuple"
            }
          ],
          "internalType": "struct PrePosition",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "pre",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "oracleVersion",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openPosition",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "closePosition",
              "type": "tuple"
            }
          ],
          "internalType": "struct PrePosition",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "rate",
      "outputs": [
        {
          "internalType": "Fixed18",
          "name": "",
          "type": "int256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "shortfall",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "snapshot",
      "outputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "productAddress",
              "type": "address"
            },
            {
              "internalType": "address",
              "name": "userAddress",
              "type": "address"
            },
            {
              "internalType": "UFixed18",
              "name": "collateral",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "maintenance",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "oracleVersion",
                  "type": "uint256"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "openPosition",
                  "type": "tuple"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "closePosition",
                  "type": "tuple"
                }
              ],
              "internalType": "struct PrePosition",
              "name": "pre",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "position",
              "type": "tuple"
            },
            {
              "internalType": "bool",
              "name": "liquidatable",
              "type": "bool"
            },
            {
              "internalType": "bool",
              "name": "liquidating",
              "type": "bool"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openInterest",
              "type": "tuple"
            },
            {
              "internalType": "UFixed18",
              "name": "fees",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "exposure",
              "type": "uint256"
            }
          ],
          "internalType": "struct IPerennialLens.UserProductSnapshot",
          "name": "_snapshot",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "snapshot",
      "outputs": [
        {
          "components": [
            {
              "components": [
                {
                  "internalType": "string",
                  "name": "name",
                  "type": "string"
                },
                {
                  "internalType": "string",
                  "name": "symbol",
                  "type": "string"
                },
                {
                  "components": [
                    {
                      "internalType": "enum PayoffDefinitionLib.PayoffType",
                      "name": "payoffType",
                      "type": "uint8"
                    },
                    {
                      "internalType": "enum PayoffDefinitionLib.PayoffDirection",
                      "name": "payoffDirection",
                      "type": "uint8"
                    },
                    {
                      "internalType": "bytes30",
                      "name": "data",
                      "type": "bytes30"
                    }
                  ],
                  "internalType": "struct PayoffDefinition",
                  "name": "payoffDefinition",
                  "type": "tuple"
                },
                {
                  "internalType": "contract IOracleProvider",
                  "name": "oracle",
                  "type": "address"
                },
                {
                  "internalType": "UFixed18",
                  "name": "maintenance",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "fundingFee",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "makerFee",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "takerFee",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "makerLimit",
                  "type": "uint256"
                },
                {
                  "components": [
                    {
                      "internalType": "PackedFixed18",
                      "name": "minRate",
                      "type": "int128"
                    },
                    {
                      "internalType": "PackedFixed18",
                      "name": "maxRate",
                      "type": "int128"
                    },
                    {
                      "internalType": "PackedFixed18",
                      "name": "targetRate",
                      "type": "int128"
                    },
                    {
                      "internalType": "PackedUFixed18",
                      "name": "targetUtilization",
                      "type": "uint128"
                    }
                  ],
                  "internalType": "struct JumpRateUtilizationCurve",
                  "name": "utilizationCurve",
                  "type": "tuple"
                }
              ],
              "internalType": "struct IProduct.ProductInfo",
              "name": "productInfo",
              "type": "tuple"
            },
            {
              "internalType": "address",
              "name": "productAddress",
              "type": "address"
            },
            {
              "internalType": "Fixed18",
              "name": "rate",
              "type": "int256"
            },
            {
              "internalType": "Fixed18",
              "name": "dailyRate",
              "type": "int256"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "version",
                  "type": "uint256"
                },
                {
                  "internalType": "uint256",
                  "name": "timestamp",
                  "type": "uint256"
                },
                {
                  "internalType": "Fixed18",
                  "name": "price",
                  "type": "int256"
                }
              ],
              "internalType": "struct IOracleProvider.OracleVersion",
              "name": "latestVersion",
              "type": "tuple"
            },
            {
              "internalType": "UFixed18",
              "name": "maintenance",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "collateral",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "shortfall",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "oracleVersion",
                  "type": "uint256"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "openPosition",
                  "type": "tuple"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "closePosition",
                  "type": "tuple"
                }
              ],
              "internalType": "struct PrePosition",
              "name": "pre",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "position",
              "type": "tuple"
            },
            {
              "internalType": "UFixed18",
              "name": "productFee",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "protocolFee",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openInterest",
              "type": "tuple"
            }
          ],
          "internalType": "struct IPerennialLens.ProductSnapshot",
          "name": "_snapshot",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct[]",
          "name": "productAddresses",
          "type": "address[]"
        }
      ],
      "name": "snapshots",
      "outputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "productAddress",
              "type": "address"
            },
            {
              "internalType": "address",
              "name": "userAddress",
              "type": "address"
            },
            {
              "internalType": "UFixed18",
              "name": "collateral",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "maintenance",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "oracleVersion",
                  "type": "uint256"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "openPosition",
                  "type": "tuple"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "closePosition",
                  "type": "tuple"
                }
              ],
              "internalType": "struct PrePosition",
              "name": "pre",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "position",
              "type": "tuple"
            },
            {
              "internalType": "bool",
              "name": "liquidatable",
              "type": "bool"
            },
            {
              "internalType": "bool",
              "name": "liquidating",
              "type": "bool"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openInterest",
              "type": "tuple"
            },
            {
              "internalType": "UFixed18",
              "name": "fees",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "exposure",
              "type": "uint256"
            }
          ],
          "internalType": "struct IPerennialLens.UserProductSnapshot[]",
          "name": "_snapshots",
          "type": "tuple[]"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct[]",
          "name": "productAddresses",
          "type": "address[]"
        }
      ],
      "name": "snapshots",
      "outputs": [
        {
          "components": [
            {
              "components": [
                {
                  "internalType": "string",
                  "name": "name",
                  "type": "string"
                },
                {
                  "internalType": "string",
                  "name": "symbol",
                  "type": "string"
                },
                {
                  "components": [
                    {
                      "internalType": "enum PayoffDefinitionLib.PayoffType",
                      "name": "payoffType",
                      "type": "uint8"
                    },
                    {
                      "internalType": "enum PayoffDefinitionLib.PayoffDirection",
                      "name": "payoffDirection",
                      "type": "uint8"
                    },
                    {
                      "internalType": "bytes30",
                      "name": "data",
                      "type": "bytes30"
                    }
                  ],
                  "internalType": "struct PayoffDefinition",
                  "name": "payoffDefinition",
                  "type": "tuple"
                },
                {
                  "internalType": "contract IOracleProvider",
                  "name": "oracle",
                  "type": "address"
                },
                {
                  "internalType": "UFixed18",
                  "name": "maintenance",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "fundingFee",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "makerFee",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "takerFee",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "makerLimit",
                  "type": "uint256"
                },
                {
                  "components": [
                    {
                      "internalType": "PackedFixed18",
                      "name": "minRate",
                      "type": "int128"
                    },
                    {
                      "internalType": "PackedFixed18",
                      "name": "maxRate",
                      "type": "int128"
                    },
                    {
                      "internalType": "PackedFixed18",
                      "name": "targetRate",
                      "type": "int128"
                    },
                    {
                      "internalType": "PackedUFixed18",
                      "name": "targetUtilization",
                      "type": "uint128"
                    }
                  ],
                  "internalType": "struct JumpRateUtilizationCurve",
                  "name": "utilizationCurve",
                  "type": "tuple"
                }
              ],
              "internalType": "struct IProduct.ProductInfo",
              "name": "productInfo",
              "type": "tuple"
            },
            {
              "internalType": "address",
              "name": "productAddress",
              "type": "address"
            },
            {
              "internalType": "Fixed18",
              "name": "rate",
              "type": "int256"
            },
            {
              "internalType": "Fixed18",
              "name": "dailyRate",
              "type": "int256"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "version",
                  "type": "uint256"
                },
                {
                  "internalType": "uint256",
                  "name": "timestamp",
                  "type": "uint256"
                },
                {
                  "internalType": "Fixed18",
                  "name": "price",
                  "type": "int256"
                }
              ],
              "internalType": "struct IOracleProvider.OracleVersion",
              "name": "latestVersion",
              "type": "tuple"
            },
            {
              "internalType": "UFixed18",
              "name": "maintenance",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "collateral",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "shortfall",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "oracleVersion",
                  "type": "uint256"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "openPosition",
                  "type": "tuple"
                },
                {
                  "components": [
                    {
                      "internalType": "UFixed18",
                      "name": "maker",
                      "type": "uint256"
                    },
                    {
                      "internalType": "UFixed18",
                      "name": "taker",
                      "type": "uint256"
                    }
                  ],
                  "internalType": "struct Position",
                  "name": "closePosition",
                  "type": "tuple"
                }
              ],
              "internalType": "struct PrePosition",
              "name": "pre",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "position",
              "type": "tuple"
            },
            {
              "internalType": "UFixed18",
              "name": "productFee",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "protocolFee",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openInterest",
              "type": "tuple"
            }
          ],
          "internalType": "struct IPerennialLens.ProductSnapshot[]",
          "name": "_snapshots",
          "type": "tuple[]"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "symbol",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "unclaimedIncentiveRewards",
      "outputs": [
        {
          "internalType": "Token18[]",
          "name": "tokens",
          "type": "address[]"
        },
        {
          "internalType": "UFixed18[]",
          "name": "amounts",
          "type": "uint256[]"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256[]",
          "name": "programIds",
          "type": "uint256[]"
        }
      ],
      "name": "unclaimedIncentiveRewards",
      "outputs": [
        {
          "internalType": "Token18[]",
          "name": "tokens",
          "type": "address[]"
        },
        {
          "internalType": "UFixed18[]",
          "name": "amounts",
          "type": "uint256[]"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "userPosition",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "oracleVersion",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "openPosition",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "closePosition",
              "type": "tuple"
            }
          ],
          "internalType": "struct PrePosition",
          "name": "",
          "type": "tuple"
        },
        {
          "components": [
            {
              "internalType": "UFixed18",
              "name": "maker",
              "type": "uint256"
            },
            {
              "internalType": "UFixed18",
              "name": "taker",
              "type": "uint256"
            }
          ],
          "internalType": "struct Position",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0x9ad7b0b825fbc79c082f3dead380bb63ca7113803df5a8db98567efbc3814770",
  "receipt": {
    "to": null,
    "from": "0x66a7fdb96c583c59597de16d8b2b989231415339",
    "contractAddress": "0x68f680607a5c32cab860f84f5f5e9f9497f66535",
    "transactionIndex": "0x0",
    "gasUsed": "0x4d5b67",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x19b97f05a225cb3ec4f8718544af9051965b7ea09c165b4aa09a67ee932cb5e9",
    "transactionHash": "0x55e7b2d656159c75187e024ea14a7390eb9e4295ef7e2301e9a0baba6f53d1d3",
    "logs": [],
    "blockNumber": "0x2057456",
    "cumulativeGasUsed": "0x4d5b67",
    "status": "0x1"
  },
  "args": ["0x1927DE7c9765Ae74050D1d0aa8BB0e93D737F579"],
  "numDeployments": 1,
  "solcInputHash": "dd0d601ac153d6a2cb60f335fa990f18",
  "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IController\",\"name\":\"_controller\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"versions\",\"type\":\"uint256[]\"}],\"name\":\"atVersions\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"Fixed18\",\"name\":\"price\",\"type\":\"int256\"}],\"internalType\":\"struct IOracleProvider.OracleVersion[]\",\"name\":\"prices\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract ICollateral\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"dailyRate\",\"outputs\":[{\"internalType\":\"Fixed18\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"exposure\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"fees\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"fees\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"protocolFees\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"productFees\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"globalPosition\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"info\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"enum PayoffDefinitionLib.PayoffType\",\"name\":\"payoffType\",\"type\":\"uint8\"},{\"internalType\":\"enum PayoffDefinitionLib.PayoffDirection\",\"name\":\"payoffDirection\",\"type\":\"uint8\"},{\"internalType\":\"bytes30\",\"name\":\"data\",\"type\":\"bytes30\"}],\"internalType\":\"struct PayoffDefinition\",\"name\":\"payoffDefinition\",\"type\":\"tuple\"},{\"internalType\":\"contract IOracleProvider\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"fundingFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"makerFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"takerFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"makerLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"PackedFixed18\",\"name\":\"minRate\",\"type\":\"int128\"},{\"internalType\":\"PackedFixed18\",\"name\":\"maxRate\",\"type\":\"int128\"},{\"internalType\":\"PackedFixed18\",\"name\":\"targetRate\",\"type\":\"int128\"},{\"internalType\":\"PackedUFixed18\",\"name\":\"targetUtilization\",\"type\":\"uint128\"}],\"internalType\":\"struct JumpRateUtilizationCurve\",\"name\":\"utilizationCurve\",\"type\":\"tuple\"}],\"internalType\":\"struct IProduct.ProductInfo\",\"name\":\"_info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"latestVersion\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"Fixed18\",\"name\":\"price\",\"type\":\"int256\"}],\"internalType\":\"struct IOracleProvider.OracleVersion\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"liquidatable\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"maintenance\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"positionSize\",\"type\":\"uint256\"}],\"name\":\"maintenanceRequired\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"openInterest\",\"outputs\":[{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"openInterest\",\"outputs\":[{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"position\",\"outputs\":[{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"position\",\"outputs\":[{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"pre\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"pre\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"rate\",\"outputs\":[{\"internalType\":\"Fixed18\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"shortfall\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"snapshot\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"pre\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"position\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"liquidatable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openInterest\",\"type\":\"tuple\"},{\"internalType\":\"UFixed18\",\"name\":\"fees\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"exposure\",\"type\":\"uint256\"}],\"internalType\":\"struct IPerennialLens.UserProductSnapshot\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"snapshot\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"enum PayoffDefinitionLib.PayoffType\",\"name\":\"payoffType\",\"type\":\"uint8\"},{\"internalType\":\"enum PayoffDefinitionLib.PayoffDirection\",\"name\":\"payoffDirection\",\"type\":\"uint8\"},{\"internalType\":\"bytes30\",\"name\":\"data\",\"type\":\"bytes30\"}],\"internalType\":\"struct PayoffDefinition\",\"name\":\"payoffDefinition\",\"type\":\"tuple\"},{\"internalType\":\"contract IOracleProvider\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"fundingFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"makerFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"takerFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"makerLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"PackedFixed18\",\"name\":\"minRate\",\"type\":\"int128\"},{\"internalType\":\"PackedFixed18\",\"name\":\"maxRate\",\"type\":\"int128\"},{\"internalType\":\"PackedFixed18\",\"name\":\"targetRate\",\"type\":\"int128\"},{\"internalType\":\"PackedUFixed18\",\"name\":\"targetUtilization\",\"type\":\"uint128\"}],\"internalType\":\"struct JumpRateUtilizationCurve\",\"name\":\"utilizationCurve\",\"type\":\"tuple\"}],\"internalType\":\"struct IProduct.ProductInfo\",\"name\":\"productInfo\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"internalType\":\"Fixed18\",\"name\":\"rate\",\"type\":\"int256\"},{\"internalType\":\"Fixed18\",\"name\":\"dailyRate\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"Fixed18\",\"name\":\"price\",\"type\":\"int256\"}],\"internalType\":\"struct IOracleProvider.OracleVersion\",\"name\":\"latestVersion\",\"type\":\"tuple\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"shortfall\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"pre\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"position\",\"type\":\"tuple\"},{\"internalType\":\"UFixed18\",\"name\":\"productFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openInterest\",\"type\":\"tuple\"}],\"internalType\":\"struct IPerennialLens.ProductSnapshot\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct[]\",\"name\":\"productAddresses\",\"type\":\"address[]\"}],\"name\":\"snapshots\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"pre\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"position\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"liquidatable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openInterest\",\"type\":\"tuple\"},{\"internalType\":\"UFixed18\",\"name\":\"fees\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"exposure\",\"type\":\"uint256\"}],\"internalType\":\"struct IPerennialLens.UserProductSnapshot[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct[]\",\"name\":\"productAddresses\",\"type\":\"address[]\"}],\"name\":\"snapshots\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"enum PayoffDefinitionLib.PayoffType\",\"name\":\"payoffType\",\"type\":\"uint8\"},{\"internalType\":\"enum PayoffDefinitionLib.PayoffDirection\",\"name\":\"payoffDirection\",\"type\":\"uint8\"},{\"internalType\":\"bytes30\",\"name\":\"data\",\"type\":\"bytes30\"}],\"internalType\":\"struct PayoffDefinition\",\"name\":\"payoffDefinition\",\"type\":\"tuple\"},{\"internalType\":\"contract IOracleProvider\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"fundingFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"makerFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"takerFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"makerLimit\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"PackedFixed18\",\"name\":\"minRate\",\"type\":\"int128\"},{\"internalType\":\"PackedFixed18\",\"name\":\"maxRate\",\"type\":\"int128\"},{\"internalType\":\"PackedFixed18\",\"name\":\"targetRate\",\"type\":\"int128\"},{\"internalType\":\"PackedUFixed18\",\"name\":\"targetUtilization\",\"type\":\"uint128\"}],\"internalType\":\"struct JumpRateUtilizationCurve\",\"name\":\"utilizationCurve\",\"type\":\"tuple\"}],\"internalType\":\"struct IProduct.ProductInfo\",\"name\":\"productInfo\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"internalType\":\"Fixed18\",\"name\":\"rate\",\"type\":\"int256\"},{\"internalType\":\"Fixed18\",\"name\":\"dailyRate\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"Fixed18\",\"name\":\"price\",\"type\":\"int256\"}],\"internalType\":\"struct IOracleProvider.OracleVersion\",\"name\":\"latestVersion\",\"type\":\"tuple\"},{\"internalType\":\"UFixed18\",\"name\":\"maintenance\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"collateral\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"shortfall\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"pre\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"position\",\"type\":\"tuple\"},{\"internalType\":\"UFixed18\",\"name\":\"productFee\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openInterest\",\"type\":\"tuple\"}],\"internalType\":\"struct IPerennialLens.ProductSnapshot[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"unclaimedIncentiveRewards\",\"outputs\":[{\"internalType\":\"Token18[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"UFixed18[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"programIds\",\"type\":\"uint256[]\"}],\"name\":\"unclaimedIncentiveRewards\",\"outputs\":[{\"internalType\":\"Token18[]\",\"name\":\"tokens\",\"type\":\"address[]\"},{\"internalType\":\"UFixed18[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"userPosition\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"oracleVersion\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"openPosition\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"closePosition\",\"type\":\"tuple\"}],\"internalType\":\"struct PrePosition\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"atVersions(address,uint256[])\":{\"params\":{\"product\":\"Product address\",\"versions\":\"Oracle versions to query\"},\"returns\":{\"prices\":\"Product prices at specified versions\"}},\"collateral()\":{\"returns\":{\"_0\":\"Protocol collateral address\"}},\"collateral(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Total collateral for product\"}},\"collateral(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"User deposited collateral for product\"}},\"constructor\":{\"params\":{\"_controller\":\"Protocol controller address\"}},\"dailyRate(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Product current funding extrapolated to a daily rate\"}},\"exposure(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"User's exposure (openInterest * utilization) after settle\"}},\"fees(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"productFees\":\"fees accrued by the product owner\",\"protocolFees\":\"fees accrued by the protocol\"}},\"fees(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"sum of all fees accrued by the account\"}},\"globalPosition(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Product pre-position\",\"_1\":\"Product position\"}},\"info(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_info\":\"of the product\"}},\"latestVersion(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Product latest price\"}},\"liquidatable(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"Whether or not the user's position eligible to be liquidated\"}},\"maintenance(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"Maximum of user maintenance, and maintenanceNext\"}},\"maintenanceRequired(address,address,uint256)\":{\"params\":{\"account\":\"Account address\",\"positionSize\":\"size of position for maintenance calculation\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"Maintenance required for position in product\"}},\"name(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Name of the product\"}},\"openInterest(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Product maker and taker position multiplied by latest price after settle\"}},\"openInterest(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"User's maker or taker position multiplied by latest price after settle\"}},\"position(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"product position\"}},\"position(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"User position\"}},\"pre(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Product pre-position\"}},\"pre(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"User pre-position\"}},\"rate(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Product current funding rate\"}},\"shortfall(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Total shortfall for product\"}},\"snapshot(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Snapshot for the product after settle\"}},\"snapshot(address,address)\":{\"params\":{\"account\":\"User addresses\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"UserSnapshot for the product after settle\"}},\"snapshots(address,address[])\":{\"params\":{\"account\":\"User addresses\",\"productAddresses\":\"Product addresses\"},\"returns\":{\"_0\":\"UserSnapshot for each product after settle\"}},\"snapshots(address[])\":{\"params\":{\"productAddresses\":\"Product addresses\"},\"returns\":{\"_0\":\"Snapshot for each product after settle\"}},\"symbol(address)\":{\"params\":{\"product\":\"Product address\"},\"returns\":{\"_0\":\"Symbol of the product\"}},\"unclaimedIncentiveRewards(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"amounts\":\"Token amounts of unclaimed incentive rewards for given product\",\"tokens\":\"Token addresses of unclaimed incentive rewards for given product\"}},\"unclaimedIncentiveRewards(address,address,uint256[])\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\",\"programIds\":\"Program IDs to query\"},\"returns\":{\"amounts\":\"Token amounts of unclaimed incentive rewards for given program IDs\",\"tokens\":\"Token addresses of unclaimed incentive rewards for given program IDs\"}},\"userPosition(address,address)\":{\"params\":{\"account\":\"Account address\",\"product\":\"Product address\"},\"returns\":{\"_0\":\"User pre-position\",\"_1\":\"User position\"}}},\"stateVariables\":{\"controller\":{\"return\":\"Protocol controller\",\"returns\":{\"_0\":\"Protocol controller\"}}},\"title\":\"Lens contract to conveniently pull protocol data\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"atVersions(address,uint256[])\":{\"notice\":\"Prices of product at specified versions after settle\"},\"collateral()\":{\"notice\":\"Protocol collateral address\"},\"collateral(address)\":{\"notice\":\"Product total collateral amount after settle\"},\"collateral(address,address)\":{\"notice\":\"User collateral amount for product after settle\"},\"controller()\":{\"notice\":\"Protocol controller\"},\"dailyRate(address)\":{\"notice\":\"Product funding extrapolated to a daily rate after settle\"},\"exposure(address,address)\":{\"notice\":\"User's exposure in product after settle\"},\"fees(address)\":{\"notice\":\"Fees accumulated by product and protocol treasuries after settle\"},\"fees(address,address)\":{\"notice\":\"Fees accumulated by account after settle\"},\"globalPosition(address)\":{\"notice\":\"Product pre-position and position after settle\"},\"info(address)\":{\"notice\":\"Returns the info of the provided `product`\"},\"latestVersion(address)\":{\"notice\":\"Current price of product after settle\"},\"liquidatable(address,address)\":{\"notice\":\"User liquidatble status for product after settle\"},\"maintenance(address,address)\":{\"notice\":\"User maintenance amount for product after settle\"},\"maintenanceRequired(address,address,uint256)\":{\"notice\":\"User's maintenance required for position size in product after settle\"},\"name(address)\":{\"notice\":\"Returns the name of the provided `product`\"},\"openInterest(address)\":{\"notice\":\"Product total open interest after settle\"},\"openInterest(address,address)\":{\"notice\":\"User's open interest in product after settle\"},\"position(address)\":{\"notice\":\"Product position after settle\"},\"position(address,address)\":{\"notice\":\"User position for product after settle\"},\"pre(address)\":{\"notice\":\"Product pre position after settle\"},\"pre(address,address)\":{\"notice\":\"User pre position for product after settle\"},\"rate(address)\":{\"notice\":\"Product funding rate after settle\"},\"shortfall(address)\":{\"notice\":\"Product total shortfall amount after settle\"},\"snapshot(address)\":{\"notice\":\"Returns the snapshot of the provided `product`\"},\"snapshot(address,address)\":{\"notice\":\"Returns the user snapshot for the provided `product`\"},\"snapshots(address,address[])\":{\"notice\":\"Returns the user snapshots for the provided `productAddresses`\"},\"snapshots(address[])\":{\"notice\":\"Returns the snapshots of the provided `productAddresses`\"},\"symbol(address)\":{\"notice\":\"Returns the symbol of the provided `product`\"},\"unclaimedIncentiveRewards(address,address)\":{\"notice\":\"User's unclaimed rewards for all programs for product after settle\"},\"unclaimedIncentiveRewards(address,address,uint256[])\":{\"notice\":\"User's unclaimed rewards for provided programs for product after settle\"},\"userPosition(address,address)\":{\"notice\":\"User pre-position and position for product after settle\"}},\"notice\":\"All functions should be called using `callStatic`\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/lens/PerennialLens.sol\":\"PerennialLens\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\n\\ninterface IOracleProvider {\\n    /// @dev A singular oracle version with its corresponding data\\n    struct OracleVersion {\\n        /// @dev The iterative version\\n        uint256 version;\\n\\n        /// @dev the timestamp of the oracle update\\n        uint256 timestamp;\\n\\n        /// @dev The oracle price of the corresponding version\\n        Fixed18 price;\\n    }\\n\\n    function sync() external returns (OracleVersion memory);\\n    function currentVersion() external view returns (OracleVersion memory);\\n    function atVersion(uint256 oracleVersion) external view returns (OracleVersion memory);\\n}\\n\",\"keccak256\":\"0xde0f20d468ba8b91addfc356e13f2c74a4dc8abe68be323942217c723775d9c1\",\"license\":\"Apache-2.0\"},\"@equilibria/root/curve/CurveMath.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../number/types/UFixed18.sol\\\";\\nimport \\\"../number/types/Fixed18.sol\\\";\\n\\n/**\\n * @title CurveMath\\n * @notice Library for managing math operations for utilization curves.\\n */\\nlibrary CurveMath {\\n    error CurveMathOutOfBoundsError();\\n\\n    /**\\n     * @notice Computes a linear interpolation between two points\\n     * @param startX First point's x-coordinate\\n     * @param startY First point's y-coordinate\\n     * @param endX Second point's x-coordinate\\n     * @param endY Second point's y-coordinate\\n     * @param targetX x-coordinate to interpolate\\n     * @return y-coordinate for `targetX` along the line from (`startX`, `startY`) -> (`endX`, `endY`)\\n     */\\n    function linearInterpolation(\\n        UFixed18 startX,\\n        Fixed18 startY,\\n        UFixed18 endX,\\n        Fixed18 endY,\\n        UFixed18 targetX\\n    ) internal pure returns (Fixed18) {\\n        if (targetX.lt(startX) || targetX.gt(endX)) revert CurveMathOutOfBoundsError();\\n\\n        UFixed18 xRange = endX.sub(startX);\\n        Fixed18 yRange = endY.sub(startY);\\n        UFixed18 xRatio = targetX.sub(startX).div(xRange);\\n        return yRange.mul(Fixed18Lib.from(xRatio)).add(startY);\\n    }\\n}\\n\",\"keccak256\":\"0x60d159f9ddf0dbe81124ecad58bba734b4cf82877637ff8d9d7f3e92f2da4ded\",\"license\":\"Apache-2.0\"},\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../CurveMath.sol\\\";\\nimport \\\"../../number/types/PackedUFixed18.sol\\\";\\nimport \\\"../../number/types/PackedFixed18.sol\\\";\\n\\n/// @dev JumpRateUtilizationCurve type\\nstruct JumpRateUtilizationCurve {\\n    PackedFixed18 minRate;\\n    PackedFixed18 maxRate;\\n    PackedFixed18 targetRate;\\n    PackedUFixed18 targetUtilization;\\n}\\nusing JumpRateUtilizationCurveLib for JumpRateUtilizationCurve global;\\ntype JumpRateUtilizationCurveStorage is bytes32;\\nusing JumpRateUtilizationCurveStorageLib for JumpRateUtilizationCurveStorage global;\\n\\n/**\\n * @title JumpRateUtilizationCurveLib\\n * @notice Library for the Jump Rate utilization curve type\\n */\\nlibrary JumpRateUtilizationCurveLib {\\n    /**\\n     * @notice Computes the corresponding rate for a utilization ratio\\n     * @param utilization The utilization ratio\\n     * @return The corresponding rate\\n     */\\n    function compute(JumpRateUtilizationCurve memory self, UFixed18 utilization) internal pure returns (Fixed18) {\\n        UFixed18 targetUtilization = self.targetUtilization.unpack();\\n        if (utilization.lt(targetUtilization)) {\\n            return CurveMath.linearInterpolation(\\n                UFixed18Lib.ZERO,\\n                self.minRate.unpack(),\\n                targetUtilization,\\n                self.targetRate.unpack(),\\n                utilization\\n            );\\n        }\\n        if (utilization.lt(UFixed18Lib.ONE)) {\\n            return CurveMath.linearInterpolation(\\n                targetUtilization,\\n                self.targetRate.unpack(),\\n                UFixed18Lib.ONE,\\n                self.maxRate.unpack(),\\n                utilization\\n            );\\n        }\\n        return self.maxRate.unpack();\\n    }\\n}\\n\\nlibrary JumpRateUtilizationCurveStorageLib {\\n    function read(JumpRateUtilizationCurveStorage self) internal view returns (JumpRateUtilizationCurve memory) {\\n        return _storagePointer(self);\\n    }\\n\\n    function store(JumpRateUtilizationCurveStorage self, JumpRateUtilizationCurve memory value) internal {\\n        JumpRateUtilizationCurve storage storagePointer = _storagePointer(self);\\n\\n        storagePointer.minRate = value.minRate;\\n        storagePointer.maxRate = value.maxRate;\\n        storagePointer.targetRate = value.targetRate;\\n        storagePointer.targetUtilization = value.targetUtilization;\\n    }\\n\\n    function _storagePointer(JumpRateUtilizationCurveStorage self)\\n    private pure returns (JumpRateUtilizationCurve storage pointer) {\\n        assembly { pointer.slot := self }\\n    }\\n}\",\"keccak256\":\"0xae202813874bc306d51b3dab8194c86f6483bb20bf1f673ddaee16aa8de567ff\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/Fixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/SignedMath.sol\\\";\\nimport \\\"./UFixed18.sol\\\";\\nimport \\\"./PackedFixed18.sol\\\";\\n\\n/// @dev Fixed18 type\\ntype Fixed18 is int256;\\nusing Fixed18Lib for Fixed18 global;\\ntype Fixed18Storage is bytes32;\\nusing Fixed18StorageLib for Fixed18Storage global;\\n\\n/**\\n * @title Fixed18Lib\\n * @notice Library for the signed fixed-decimal type.\\n */\\nlibrary Fixed18Lib {\\n    error Fixed18OverflowError(uint256 value);\\n    error Fixed18PackingOverflowError(int256 value);\\n    error Fixed18PackingUnderflowError(int256 value);\\n\\n    int256 private constant BASE = 1e18;\\n    Fixed18 public constant ZERO = Fixed18.wrap(0);\\n    Fixed18 public constant ONE = Fixed18.wrap(BASE);\\n    Fixed18 public constant NEG_ONE = Fixed18.wrap(-1 * BASE);\\n    Fixed18 public constant MAX = Fixed18.wrap(type(int256).max);\\n    Fixed18 public constant MIN = Fixed18.wrap(type(int256).min);\\n\\n    /**\\n     * @notice Creates a signed fixed-decimal from an unsigned fixed-decimal\\n     * @param a Unsigned fixed-decimal\\n     * @return New signed fixed-decimal\\n     */\\n    function from(UFixed18 a) internal pure returns (Fixed18) {\\n        uint256 value = UFixed18.unwrap(a);\\n        if (value > uint256(type(int256).max)) revert Fixed18OverflowError(value);\\n        return Fixed18.wrap(int256(value));\\n    }\\n\\n    /**\\n     * @notice Creates a signed fixed-decimal from a sign and an unsigned fixed-decimal\\n     * @param s Sign\\n     * @param m Unsigned fixed-decimal magnitude\\n     * @return New signed fixed-decimal\\n     */\\n    function from(int256 s, UFixed18 m) internal pure returns (Fixed18) {\\n        if (s > 0) return from(m);\\n        if (s < 0) return Fixed18.wrap(-1 * Fixed18.unwrap(from(m)));\\n        return ZERO;\\n    }\\n\\n    /**\\n     * @notice Creates a signed fixed-decimal from a signed integer\\n     * @param a Signed number\\n     * @return New signed fixed-decimal\\n     */\\n    function from(int256 a) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(a * BASE);\\n    }\\n\\n    /**\\n     * @notice Creates a packed signed fixed-decimal from an signed fixed-decimal\\n     * @param a signed fixed-decimal\\n     * @return New packed signed fixed-decimal\\n     */\\n    function pack(Fixed18 a) internal pure returns (PackedFixed18) {\\n        int256 value = Fixed18.unwrap(a);\\n        if (value > type(int128).max) revert Fixed18PackingOverflowError(value);\\n        if (value < type(int128).min) revert Fixed18PackingUnderflowError(value);\\n        return PackedFixed18.wrap(int128(value));\\n    }\\n\\n    /**\\n     * @notice Returns whether the signed fixed-decimal is equal to zero.\\n     * @param a Signed fixed-decimal\\n     * @return Whether the signed fixed-decimal is zero.\\n     */\\n    function isZero(Fixed18 a) internal pure returns (bool) {\\n        return Fixed18.unwrap(a) == 0;\\n    }\\n\\n    /**\\n     * @notice Adds two signed fixed-decimals `a` and `b` together\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Resulting summed signed fixed-decimal\\n     */\\n    function add(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(Fixed18.unwrap(a) + Fixed18.unwrap(b));\\n    }\\n\\n    /**\\n     * @notice Subtracts signed fixed-decimal `b` from `a`\\n     * @param a Signed fixed-decimal to subtract from\\n     * @param b Signed fixed-decimal to subtract\\n     * @return Resulting subtracted signed fixed-decimal\\n     */\\n    function sub(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(Fixed18.unwrap(a) - Fixed18.unwrap(b));\\n    }\\n\\n    /**\\n     * @notice Multiplies two signed fixed-decimals `a` and `b` together\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Resulting multiplied signed fixed-decimal\\n     */\\n    function mul(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / BASE);\\n    }\\n\\n    /**\\n     * @notice Divides signed fixed-decimal `a` by `b`\\n     * @param a Signed fixed-decimal to divide\\n     * @param b Signed fixed-decimal to divide by\\n     * @return Resulting divided signed fixed-decimal\\n     */\\n    function div(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(Fixed18.unwrap(a) * BASE / Fixed18.unwrap(b));\\n    }\\n\\n    /**\\n     * @notice Divides unsigned fixed-decimal `a` by `b`\\n     * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0`, `MAX` for `n/0`, and `MIN` for `-n/0`.\\n     * @param a Unsigned fixed-decimal to divide\\n     * @param b Unsigned fixed-decimal to divide by\\n     * @return Resulting divided unsigned fixed-decimal\\n     */\\n    function unsafeDiv(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        if (isZero(b)) {\\n            if (gt(a, ZERO)) return MAX;\\n            if (lt(a, ZERO)) return MIN;\\n            return ONE;\\n        } else {\\n            return div(a, b);\\n        }\\n    }\\n\\n    /**\\n     * @notice Computes a * b / c without loss of precision due to BASE conversion\\n     * @param a First signed fixed-decimal\\n     * @param b Signed number to multiply by\\n     * @param c Signed number to divide by\\n     * @return Resulting computation\\n     */\\n    function muldiv(Fixed18 a, int256 b, int256 c) internal pure returns (Fixed18) {\\n        return muldiv(a, Fixed18.wrap(b), Fixed18.wrap(c));\\n    }\\n\\n    /**\\n     * @notice Computes a * b / c without loss of precision due to BASE conversion\\n     * @param a First signed fixed-decimal\\n     * @param b Signed fixed-decimal to multiply by\\n     * @param c Signed fixed-decimal to divide by\\n     * @return Resulting computation\\n     */\\n    function muldiv(Fixed18 a, Fixed18 b, Fixed18 c) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(Fixed18.unwrap(a) * Fixed18.unwrap(b) / Fixed18.unwrap(c));\\n    }\\n\\n    /**\\n     * @notice Returns whether signed fixed-decimal `a` is equal to `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Whether `a` is equal to `b`\\n     */\\n    function eq(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n        return compare(a, b) == 1;\\n    }\\n\\n    /**\\n     * @notice Returns whether signed fixed-decimal `a` is greater than `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Whether `a` is greater than `b`\\n     */\\n    function gt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n        return compare(a, b) == 2;\\n    }\\n\\n    /**\\n     * @notice Returns whether signed fixed-decimal `a` is less than `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Whether `a` is less than `b`\\n     */\\n    function lt(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n        return compare(a, b) == 0;\\n    }\\n\\n    /**\\n     * @notice Returns whether signed fixed-decimal `a` is greater than or equal to `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Whether `a` is greater than or equal to `b`\\n     */\\n    function gte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n        return gt(a, b) || eq(a, b);\\n    }\\n\\n    /**\\n     * @notice Returns whether signed fixed-decimal `a` is less than or equal to `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Whether `a` is less than or equal to `b`\\n     */\\n    function lte(Fixed18 a, Fixed18 b) internal pure returns (bool) {\\n        return lt(a, b) || eq(a, b);\\n    }\\n\\n    /**\\n     * @notice Compares the signed fixed-decimals `a` and `b`\\n     * @dev Returns: 2 for greater than\\n     *               1 for equal to\\n     *               0 for less than\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Compare result of `a` and `b`\\n     */\\n    function compare(Fixed18 a, Fixed18 b) internal pure returns (uint256) {\\n        (int256 au, int256 bu) = (Fixed18.unwrap(a), Fixed18.unwrap(b));\\n        if (au > bu) return 2;\\n        if (au < bu) return 0;\\n        return 1;\\n    }\\n\\n    /**\\n     * @notice Returns a signed fixed-decimal representing the ratio of `a` over `b`\\n     * @param a First signed number\\n     * @param b Second signed number\\n     * @return Ratio of `a` over `b`\\n     */\\n    function ratio(int256 a, int256 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(a * BASE / b);\\n    }\\n\\n    /**\\n     * @notice Returns the minimum of signed fixed-decimals `a` and `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Minimum of `a` and `b`\\n     */\\n    function min(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(SignedMath.min(Fixed18.unwrap(a), Fixed18.unwrap(b)));\\n    }\\n\\n    /**\\n     * @notice Returns the maximum of signed fixed-decimals `a` and `b`\\n     * @param a First signed fixed-decimal\\n     * @param b Second signed fixed-decimal\\n     * @return Maximum of `a` and `b`\\n     */\\n    function max(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(SignedMath.max(Fixed18.unwrap(a), Fixed18.unwrap(b)));\\n    }\\n\\n    /**\\n     * @notice Converts the signed fixed-decimal into an integer, truncating any decimal portion\\n     * @param a Signed fixed-decimal\\n     * @return Truncated signed number\\n     */\\n    function truncate(Fixed18 a) internal pure returns (int256) {\\n        return Fixed18.unwrap(a) / BASE;\\n    }\\n\\n    /**\\n     * @notice Returns the sign of the signed fixed-decimal\\n     * @dev Returns: -1 for negative\\n     *                0 for zero\\n     *                1 for positive\\n     * @param a Signed fixed-decimal\\n     * @return Sign of the signed fixed-decimal\\n     */\\n    function sign(Fixed18 a) internal pure returns (int256) {\\n        if (Fixed18.unwrap(a) > 0) return 1;\\n        if (Fixed18.unwrap(a) < 0) return -1;\\n        return 0;\\n    }\\n\\n    /**\\n     * @notice Returns the absolute value of the signed fixed-decimal\\n     * @param a Signed fixed-decimal\\n     * @return Absolute value of the signed fixed-decimal\\n     */\\n    function abs(Fixed18 a) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(SignedMath.abs(Fixed18.unwrap(a)));\\n    }\\n}\\n\\nlibrary Fixed18StorageLib {\\n    function read(Fixed18Storage self) internal view returns (Fixed18 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    function store(Fixed18Storage self, Fixed18 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x613587461ef3437ef33229cdda7d34ea746278721baf06e20b2e43977f43174d\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/PackedFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./Fixed18.sol\\\";\\n\\n/// @dev PackedFixed18 type\\ntype PackedFixed18 is int128;\\nusing PackedFixed18Lib for PackedFixed18 global;\\n\\n/**\\n * @title PackedFixed18Lib\\n * @dev A packed version of the Fixed18 which takes up half the storage space (two PackedFixed18 can be packed\\n *      into a single slot). Only valid within the range -1.7014118e+20 <= x <= 1.7014118e+20.\\n * @notice Library for the packed signed fixed-decimal type.\\n */\\nlibrary PackedFixed18Lib {\\n    PackedFixed18 public constant MAX = PackedFixed18.wrap(type(int128).max);\\n    PackedFixed18 public constant MIN = PackedFixed18.wrap(type(int128).min);\\n\\n    /**\\n     * @notice Creates an unpacked signed fixed-decimal from a packed signed fixed-decimal\\n     * @param self packed signed fixed-decimal\\n     * @return New unpacked signed fixed-decimal\\n     */\\n    function unpack(PackedFixed18 self) internal pure returns (Fixed18) {\\n        return Fixed18.wrap(int256(PackedFixed18.unwrap(self)));\\n    }\\n}\\n\",\"keccak256\":\"0xb52960cc8e3132e45d342bbbb1c6a96219022cd8557997933bd8250170268b64\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/PackedUFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./UFixed18.sol\\\";\\n\\n/// @dev PackedUFixed18 type\\ntype PackedUFixed18 is uint128;\\nusing PackedUFixed18Lib for PackedUFixed18 global;\\n\\n/**\\n * @title PackedUFixed18Lib\\n * @dev A packed version of the UFixed18 which takes up half the storage space (two PackedUFixed18 can be packed\\n *      into a single slot). Only valid within the range 0 <= x <= 3.4028237e+20.\\n * @notice Library for the packed unsigned fixed-decimal type.\\n */\\nlibrary PackedUFixed18Lib {\\n    PackedUFixed18 public constant MAX = PackedUFixed18.wrap(type(uint128).max);\\n\\n    /**\\n     * @notice Creates an unpacked unsigned fixed-decimal from a packed unsigned fixed-decimal\\n     * @param self packed unsigned fixed-decimal\\n     * @return New unpacked unsigned fixed-decimal\\n     */\\n    function unpack(PackedUFixed18 self) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(uint256(PackedUFixed18.unwrap(self)));\\n    }\\n}\\n\",\"keccak256\":\"0xb5c5cd32d6530b2fe75228b6be32ebcb7762f6d7988b85a6b85a289ce8256d51\",\"license\":\"Apache-2.0\"},\"@equilibria/root/number/types/UFixed18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"./Fixed18.sol\\\";\\nimport \\\"./PackedUFixed18.sol\\\";\\n\\n/// @dev UFixed18 type\\ntype UFixed18 is uint256;\\nusing UFixed18Lib for UFixed18 global;\\ntype UFixed18Storage is bytes32;\\nusing UFixed18StorageLib for UFixed18Storage global;\\n\\n/**\\n * @title UFixed18Lib\\n * @notice Library for the unsigned fixed-decimal type.\\n */\\nlibrary UFixed18Lib {\\n    error UFixed18UnderflowError(int256 value);\\n    error UFixed18PackingOverflowError(uint256 value);\\n\\n    uint256 private constant BASE = 1e18;\\n    UFixed18 public constant ZERO = UFixed18.wrap(0);\\n    UFixed18 public constant ONE = UFixed18.wrap(BASE);\\n    UFixed18 public constant MAX = UFixed18.wrap(type(uint256).max);\\n\\n    /**\\n     * @notice Creates a unsigned fixed-decimal from a signed fixed-decimal\\n     * @param a Signed fixed-decimal\\n     * @return New unsigned fixed-decimal\\n     */\\n    function from(Fixed18 a) internal pure returns (UFixed18) {\\n        int256 value = Fixed18.unwrap(a);\\n        if (value < 0) revert UFixed18UnderflowError(value);\\n        return UFixed18.wrap(uint256(value));\\n    }\\n\\n    /**\\n     * @notice Creates a unsigned fixed-decimal from a unsigned integer\\n     * @param a Unsigned number\\n     * @return New unsigned fixed-decimal\\n     */\\n    function from(uint256 a) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(a * BASE);\\n    }\\n\\n    /**\\n     * @notice Creates a packed unsigned fixed-decimal from an unsigned fixed-decimal\\n     * @param a unsigned fixed-decimal\\n     * @return New packed unsigned fixed-decimal\\n     */\\n    function pack(UFixed18 a) internal pure returns (PackedUFixed18) {\\n        uint256 value = UFixed18.unwrap(a);\\n        if (value > type(uint128).max) revert UFixed18PackingOverflowError(value);\\n        return PackedUFixed18.wrap(uint128(value));\\n    }\\n\\n    /**\\n     * @notice Returns whether the unsigned fixed-decimal is equal to zero.\\n     * @param a Unsigned fixed-decimal\\n     * @return Whether the unsigned fixed-decimal is zero.\\n     */\\n    function isZero(UFixed18 a) internal pure returns (bool) {\\n        return UFixed18.unwrap(a) == 0;\\n    }\\n\\n    /**\\n     * @notice Adds two unsigned fixed-decimals `a` and `b` together\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Resulting summed unsigned fixed-decimal\\n     */\\n    function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\\n    }\\n\\n    /**\\n     * @notice Subtracts unsigned fixed-decimal `b` from `a`\\n     * @param a Unsigned fixed-decimal to subtract from\\n     * @param b Unsigned fixed-decimal to subtract\\n     * @return Resulting subtracted unsigned fixed-decimal\\n     */\\n    function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\\n    }\\n\\n    /**\\n     * @notice Multiplies two unsigned fixed-decimals `a` and `b` together\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Resulting multiplied unsigned fixed-decimal\\n     */\\n    function mul(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / BASE);\\n    }\\n\\n    /**\\n     * @notice Divides unsigned fixed-decimal `a` by `b`\\n     * @param a Unsigned fixed-decimal to divide\\n     * @param b Unsigned fixed-decimal to divide by\\n     * @return Resulting divided unsigned fixed-decimal\\n     */\\n    function div(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(UFixed18.unwrap(a) * BASE / UFixed18.unwrap(b));\\n    }\\n\\n    /**\\n     * @notice Divides unsigned fixed-decimal `a` by `b`\\n     * @dev Does not revert on divide-by-0, instead returns `ONE` for `0/0` and `MAX` for `n/0`.\\n     * @param a Unsigned fixed-decimal to divide\\n     * @param b Unsigned fixed-decimal to divide by\\n     * @return Resulting divided unsigned fixed-decimal\\n     */\\n    function unsafeDiv(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        if (isZero(b)) {\\n            return isZero(a) ? ONE : MAX;\\n        } else {\\n            return div(a, b);\\n        }\\n    }\\n\\n    /**\\n     * @notice Computes a * b / c without loss of precision due to BASE conversion\\n     * @param a First unsigned fixed-decimal\\n     * @param b Unsigned number to multiply by\\n     * @param c Unsigned number to divide by\\n     * @return Resulting computation\\n     */\\n    function muldiv(UFixed18 a, uint256 b, uint256 c) internal pure returns (UFixed18) {\\n        return muldiv(a, UFixed18.wrap(b), UFixed18.wrap(c));\\n    }\\n\\n    /**\\n     * @notice Computes a * b / c without loss of precision due to BASE conversion\\n     * @param a First unsigned fixed-decimal\\n     * @param b Unsigned fixed-decimal to multiply by\\n     * @param c Unsigned fixed-decimal to divide by\\n     * @return Resulting computation\\n     */\\n    function muldiv(UFixed18 a, UFixed18 b, UFixed18 c) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(UFixed18.unwrap(a) * UFixed18.unwrap(b) / UFixed18.unwrap(c));\\n    }\\n\\n    /**\\n     * @notice Returns whether unsigned fixed-decimal `a` is equal to `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Whether `a` is equal to `b`\\n     */\\n    function eq(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n        return compare(a, b) == 1;\\n    }\\n\\n    /**\\n     * @notice Returns whether unsigned fixed-decimal `a` is greater than `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Whether `a` is greater than `b`\\n     */\\n    function gt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n        return compare(a, b) == 2;\\n    }\\n\\n    /**\\n     * @notice Returns whether unsigned fixed-decimal `a` is less than `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Whether `a` is less than `b`\\n     */\\n    function lt(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n        return compare(a, b) == 0;\\n    }\\n\\n    /**\\n     * @notice Returns whether unsigned fixed-decimal `a` is greater than or equal to `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Whether `a` is greater than or equal to `b`\\n     */\\n    function gte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n        return gt(a, b) || eq(a, b);\\n    }\\n\\n    /**\\n     * @notice Returns whether unsigned fixed-decimal `a` is less than or equal to `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Whether `a` is less than or equal to `b`\\n     */\\n    function lte(UFixed18 a, UFixed18 b) internal pure returns (bool) {\\n        return lt(a, b) || eq(a, b);\\n    }\\n\\n    /**\\n     * @notice Compares the unsigned fixed-decimals `a` and `b`\\n     * @dev Returns: 2 for greater than\\n     *               1 for equal to\\n     *               0 for less than\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Compare result of `a` and `b`\\n     */\\n    function compare(UFixed18 a, UFixed18 b) internal pure returns (uint256) {\\n        (uint256 au, uint256 bu) = (UFixed18.unwrap(a), UFixed18.unwrap(b));\\n        if (au > bu) return 2;\\n        if (au < bu) return 0;\\n        return 1;\\n    }\\n\\n    /**\\n     * @notice Returns a unsigned fixed-decimal representing the ratio of `a` over `b`\\n     * @param a First unsigned number\\n     * @param b Second unsigned number\\n     * @return Ratio of `a` over `b`\\n     */\\n    function ratio(uint256 a, uint256 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(a * BASE / b);\\n    }\\n\\n    /**\\n     * @notice Returns the minimum of unsigned fixed-decimals `a` and `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Minimum of `a` and `b`\\n     */\\n    function min(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(Math.min(UFixed18.unwrap(a), UFixed18.unwrap(b)));\\n    }\\n\\n    /**\\n     * @notice Returns the maximum of unsigned fixed-decimals `a` and `b`\\n     * @param a First unsigned fixed-decimal\\n     * @param b Second unsigned fixed-decimal\\n     * @return Maximum of `a` and `b`\\n     */\\n    function max(UFixed18 a, UFixed18 b) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(Math.max(UFixed18.unwrap(a), UFixed18.unwrap(b)));\\n    }\\n\\n    /**\\n     * @notice Converts the unsigned fixed-decimal into an integer, truncating any decimal portion\\n     * @param a Unsigned fixed-decimal\\n     * @return Truncated unsigned number\\n     */\\n    function truncate(UFixed18 a) internal pure returns (uint256) {\\n        return UFixed18.unwrap(a) / BASE;\\n    }\\n}\\n\\nlibrary UFixed18StorageLib {\\n    function read(UFixed18Storage self) internal view returns (UFixed18 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    function store(UFixed18Storage self, UFixed18 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x8ebef1e6c717f565b9ed545a876b5692b4007e6485c99f39d363f7405e591792\",\"license\":\"Apache-2.0\"},\"@equilibria/root/token/types/Token18.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"../../number/types/UFixed18.sol\\\";\\n\\n/// @dev Token18\\ntype Token18 is address;\\nusing Token18Lib for Token18 global;\\ntype Token18Storage is bytes32;\\nusing Token18StorageLib for Token18Storage global;\\n\\n/**\\n * @title Token18Lib\\n * @notice Library to manage 18-decimal ERC20s that is compliant with the fixed-decimal types.\\n * @dev Maintains significant gas savings over other Token implementations since no conversion take place\\n */\\nlibrary Token18Lib {\\n    using SafeERC20 for IERC20;\\n\\n    Token18 public constant ZERO = Token18.wrap(address(0));\\n\\n    /**\\n     * @notice Returns whether a token is the zero address\\n     * @param self Token to check for\\n     * @return Whether the token is the zero address\\n     */\\n    function isZero(Token18 self) internal pure returns (bool) {\\n        return Token18.unwrap(self) == Token18.unwrap(ZERO);\\n    }\\n\\n    /**\\n     * @notice Returns whether the two tokens are equal\\n     * @param a First token to compare\\n     * @param b Second token to compare\\n     * @return Whether the two tokens are equal\\n     */\\n    function eq(Token18 a, Token18 b) internal pure returns (bool) {\\n        return Token18.unwrap(a) ==  Token18.unwrap(b);\\n    }\\n\\n    /**\\n     * @notice Approves `grantee` to spend infinite tokens from the caller\\n     * @param self Token to transfer\\n     * @param grantee Address to allow spending\\n     */\\n    function approve(Token18 self, address grantee) internal {\\n        IERC20(Token18.unwrap(self)).safeApprove(grantee, type(uint256).max);\\n    }\\n\\n    /**\\n     * @notice Approves `grantee` to spend `amount` tokens from the caller\\n     * @dev There are important race conditions to be aware of when using this function\\n            with values other than 0. This will revert if moving from non-zero to non-zero amounts\\n            See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a55b7d13722e7ce850b626da2313f3e66ca1d101/contracts/token/ERC20/IERC20.sol#L57\\n     * @param self Token to transfer\\n     * @param grantee Address to allow spending\\n     * @param amount Amount of tokens to approve to spend\\n     */\\n    function approve(Token18 self, address grantee, UFixed18 amount) internal {\\n        IERC20(Token18.unwrap(self)).safeApprove(grantee, UFixed18.unwrap(amount));\\n    }\\n\\n    /**\\n     * @notice Transfers all held tokens from the caller to the `recipient`\\n     * @param self Token to transfer\\n     * @param recipient Address to receive the tokens\\n     */\\n    function push(Token18 self, address recipient) internal {\\n        push(self, recipient, balanceOf(self, address(this)));\\n    }\\n\\n    /**\\n     * @notice Transfers `amount` tokens from the caller to the `recipient`\\n     * @param self Token to transfer\\n     * @param recipient Address to transfer tokens to\\n     * @param amount Amount of tokens to transfer\\n     */\\n    function push(Token18 self, address recipient, UFixed18 amount) internal {\\n        IERC20(Token18.unwrap(self)).safeTransfer(recipient, UFixed18.unwrap(amount));\\n    }\\n\\n    /**\\n     * @notice Transfers `amount` tokens from the `benefactor` to the caller\\n     * @dev Reverts if trying to pull Ether\\n     * @param self Token to transfer\\n     * @param benefactor Address to transfer tokens from\\n     * @param amount Amount of tokens to transfer\\n     */\\n    function pull(Token18 self, address benefactor, UFixed18 amount) internal {\\n        IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, address(this), UFixed18.unwrap(amount));\\n    }\\n\\n    /**\\n     * @notice Transfers `amount` tokens from the `benefactor` to `recipient`\\n     * @dev Reverts if trying to pull Ether\\n     * @param self Token to transfer\\n     * @param benefactor Address to transfer tokens from\\n     * @param recipient Address to transfer tokens to\\n     * @param amount Amount of tokens to transfer\\n     */\\n    function pullTo(Token18 self, address benefactor, address recipient, UFixed18 amount) internal {\\n        IERC20(Token18.unwrap(self)).safeTransferFrom(benefactor, recipient, UFixed18.unwrap(amount));\\n    }\\n\\n    /**\\n     * @notice Returns the name of the token\\n     * @param self Token to check for\\n     * @return Token name\\n     */\\n    function name(Token18 self) internal view returns (string memory) {\\n        return IERC20Metadata(Token18.unwrap(self)).name();\\n    }\\n\\n    /**\\n     * @notice Returns the symbol of the token\\n     * @param self Token to check for\\n     * @return Token symbol\\n     */\\n    function symbol(Token18 self) internal view returns (string memory) {\\n        return IERC20Metadata(Token18.unwrap(self)).symbol();\\n    }\\n\\n    /**\\n     * @notice Returns the `self` token balance of the caller\\n     * @param self Token to check for\\n     * @return Token balance of the caller\\n     */\\n    function balanceOf(Token18 self) internal view returns (UFixed18) {\\n        return balanceOf(self, address(this));\\n    }\\n\\n    /**\\n     * @notice Returns the `self` token balance of `account`\\n     * @param self Token to check for\\n     * @param account Account to check\\n     * @return Token balance of the account\\n     */\\n    function balanceOf(Token18 self, address account) internal view returns (UFixed18) {\\n        return UFixed18.wrap(IERC20(Token18.unwrap(self)).balanceOf(account));\\n    }\\n}\\n\\nlibrary Token18StorageLib {\\n    function read(Token18Storage self) internal view returns (Token18 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    function store(Token18Storage self, Token18 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x6b12afaece814f0ab186200a4729e93eb685a21d3e9b5a3372ff283a7ad5dc23\",\"license\":\"Apache-2.0\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n    /**\\n     * @dev Must return an address that can be used as a delegate call target.\\n     *\\n     * {BeaconProxy} will check that this address is a contract.\\n     */\\n    function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n    using Address for address;\\n\\n    function safeTransfer(\\n        IERC20 token,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    function safeTransferFrom(\\n        IERC20 token,\\n        address from,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n    }\\n\\n    /**\\n     * @dev Deprecated. This function has issues similar to the ones found in\\n     * {IERC20-approve}, and its usage is discouraged.\\n     *\\n     * Whenever possible, use {safeIncreaseAllowance} and\\n     * {safeDecreaseAllowance} instead.\\n     */\\n    function safeApprove(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        require(\\n            (value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    function safeIncreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n\\n    function safeDecreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        unchecked {\\n            uint256 oldAllowance = token.allowance(address(this), spender);\\n            require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n            uint256 newAllowance = oldAllowance - value;\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n        }\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        if (returndata.length > 0) {\\n            // Return data is optional\\n            require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     * ====\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n     *\\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n     * constructor.\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize/address.code.length, which returns 0\\n        // for contracts in construction, since the code is only stored at the end\\n        // of the constructor execution.\\n\\n        return account.code.length > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            // Look for revert reason and bubble it up if present\\n            if (returndata.length > 0) {\\n                // The easiest way to bubble the revert reason is using memory via assembly\\n\\n                assembly {\\n                    let returndata_size := mload(returndata)\\n                    revert(add(32, returndata), returndata_size)\\n                }\\n            } else {\\n                revert(errorMessage);\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a >= b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a / b + (a % b == 0 ? 0 : 1);\\n    }\\n}\\n\",\"keccak256\":\"0xc995bddbca1ae19788db9f8b61e63385edd3fddf89693b612d5abd1a275974d2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n    /**\\n     * @dev Returns the largest of two signed numbers.\\n     */\\n    function max(int256 a, int256 b) internal pure returns (int256) {\\n        return a >= b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two signed numbers.\\n     */\\n    function min(int256 a, int256 b) internal pure returns (int256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two signed numbers without overflow.\\n     * The result is rounded towards zero.\\n     */\\n    function average(int256 a, int256 b) internal pure returns (int256) {\\n        // Formula from the book \\\"Hacker's Delight\\\"\\n        int256 x = (a & b) + ((a ^ b) >> 1);\\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\\n    }\\n\\n    /**\\n     * @dev Returns the absolute unsigned value of a signed value.\\n     */\\n    function abs(int256 n) internal pure returns (uint256) {\\n        unchecked {\\n            // must be unchecked in order to support `n = type(int256).min`\\n            return uint256(n >= 0 ? n : -n);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xb3ebde1c8d27576db912d87c3560dab14adfb9cd001be95890ec4ba035e652e7\",\"license\":\"MIT\"},\"contracts/interfaces/ICollateral.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"./IController.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface ICollateral {\\n    event Deposit(address indexed user, IProduct indexed product, UFixed18 amount);\\n    event Withdrawal(address indexed user, IProduct indexed product, UFixed18 amount);\\n    event AccountSettle(IProduct indexed product, address indexed account, Fixed18 amount, UFixed18 newShortfall);\\n    event ProductSettle(IProduct indexed product, UFixed18 protocolFee, UFixed18 productFee);\\n    event Liquidation(address indexed user, IProduct indexed product, address liquidator, UFixed18 fee);\\n    event ShortfallResolution(IProduct indexed product, UFixed18 amount);\\n    event FeeClaim(address indexed account, UFixed18 amount);\\n\\n    error CollateralCantLiquidate(UFixed18 totalMaintenance, UFixed18 totalCollateral);\\n    error CollateralInsufficientCollateralError();\\n    error CollateralUnderLimitError();\\n    error CollateralZeroAddressError();\\n\\n    function token() external view returns (Token18);\\n    function fees(address account) external view returns (UFixed18);\\n    function initialize(IController controller_) external;\\n    function depositTo(address account, IProduct product, UFixed18 amount) external;\\n    function withdrawTo(address account, IProduct product, UFixed18 amount) external;\\n    function liquidate(address account, IProduct product) external;\\n    function settleAccount(address account, Fixed18 amount) external;\\n    function settleProduct(UFixed18 amount) external;\\n    function collateral(address account, IProduct product) external view returns (UFixed18);\\n    function collateral(IProduct product) external view returns (UFixed18);\\n    function shortfall(IProduct product) external view returns (UFixed18);\\n    function liquidatable(address account, IProduct product) external view returns (bool);\\n    function liquidatableNext(address account, IProduct product) external view returns (bool);\\n    function resolveShortfall(IProduct product, UFixed18 amount) external;\\n    function claimFee() external;\\n}\\n\",\"keccak256\":\"0xa5e7fdda92702f748e6eb8701e522450035a98a05e5fc1cf66d51c52e397d914\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IContractPayoffProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\n\\ninterface IContractPayoffProvider {\\n    function payoff(Fixed18 price) external view returns (Fixed18 payoff);\\n}\\n\",\"keccak256\":\"0xd73df106d032e976fd959ee6713240e36f54277ce5f215eaec8d5a2c6720a86b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IController.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IIncentivizer.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\n\\ninterface IController {\\n    /// @dev Coordinator of a one or many products\\n    struct Coordinator {\\n        /// @dev Pending owner of the product, can accept ownership\\n        address pendingOwner;\\n\\n        /// @dev Owner of the product, allowed to update select parameters\\n        address owner;\\n\\n        /// @dev Treasury of the product, collects fees\\n        address treasury;\\n    }\\n\\n    event CollateralUpdated(ICollateral newCollateral);\\n    event IncentivizerUpdated(IIncentivizer newIncentivizer);\\n    event ProductBeaconUpdated(IBeacon newProductBeacon);\\n    event ProtocolFeeUpdated(UFixed18 newProtocolFee);\\n    event MinFundingFeeUpdated(UFixed18 newMinFundingFee);\\n    event LiquidationFeeUpdated(UFixed18 newLiquidationFee);\\n    event IncentivizationFeeUpdated(UFixed18 newIncentivizationFee);\\n    event MinCollateralUpdated(UFixed18 newMinCollateral);\\n    event ProgramsPerProductUpdated(uint256 newProgramsPerProduct);\\n    event PauserUpdated(address newPauser);\\n    event PausedUpdated(bool newPaused);\\n    event CoordinatorPendingOwnerUpdated(uint256 indexed coordinatorId, address newPendingOwner);\\n    event CoordinatorOwnerUpdated(uint256 indexed coordinatorId, address newOwner);\\n    event CoordinatorTreasuryUpdated(uint256 indexed coordinatorId, address newTreasury);\\n    event CoordinatorCreated(uint256 indexed coordinatorId, address owner);\\n    event ProductCreated(IProduct indexed product, IProduct.ProductInfo productInfo);\\n\\n    error ControllerNoZeroCoordinatorError();\\n    error ControllerNotPauserError();\\n    error ControllerNotOwnerError(uint256 controllerId);\\n    error ControllerNotPendingOwnerError(uint256 controllerId);\\n    error ControllerInvalidProtocolFeeError();\\n    error ControllerInvalidMinFundingFeeError();\\n    error ControllerInvalidLiquidationFeeError();\\n    error ControllerInvalidIncentivizationFeeError();\\n    error ControllerNotContractAddressError();\\n\\n    function collateral() external view returns (ICollateral);\\n    function incentivizer() external view returns (IIncentivizer);\\n    function productBeacon() external view returns (IBeacon);\\n    function coordinators(uint256 collateralId) external view returns (Coordinator memory);\\n    function coordinatorFor(IProduct product) external view returns (uint256);\\n    function protocolFee() external view returns (UFixed18);\\n    function minFundingFee() external view returns (UFixed18);\\n    function liquidationFee() external view returns (UFixed18);\\n    function incentivizationFee() external view returns (UFixed18);\\n    function minCollateral() external view returns (UFixed18);\\n    function programsPerProduct() external view returns (uint256);\\n    function pauser() external view returns (address);\\n    function paused() external view returns (bool);\\n    function initialize(ICollateral collateral_, IIncentivizer incentivizer_, IBeacon productBeacon_) external;\\n    function createCoordinator() external returns (uint256);\\n    function updateCoordinatorPendingOwner(uint256 coordinatorId, address newPendingOwner) external;\\n    function acceptCoordinatorOwner(uint256 coordinatorId) external;\\n    function updateCoordinatorTreasury(uint256 coordinatorId, address newTreasury) external;\\n    function createProduct(uint256 coordinatorId, IProduct.ProductInfo calldata productInfo) external returns (IProduct);\\n    function updateCollateral(ICollateral newCollateral) external;\\n    function updateIncentivizer(IIncentivizer newIncentivizer) external;\\n    function updateProductBeacon(IBeacon newProductBeacon) external;\\n    function updateProtocolFee(UFixed18 newProtocolFee) external;\\n    function updateMinFundingFee(UFixed18 newMinFundingFee) external;\\n    function updateLiquidationFee(UFixed18 newLiquidationFee) external;\\n    function updateIncentivizationFee(UFixed18 newIncentivizationFee) external;\\n    function updateMinCollateral(UFixed18 newMinCollateral) external;\\n    function updateProgramsPerProduct(uint256 newProductsPerProduct) external;\\n    function updatePauser(address newPauser) external;\\n    function updatePaused(bool newPaused) external;\\n    function isProduct(IProduct product) external view returns (bool);\\n    function owner() external view returns (address);\\n    function owner(uint256 coordinatorId) external view returns (address);\\n    function owner(IProduct product) external view returns (address);\\n    function treasury() external view returns (address);\\n    function treasury(uint256 coordinatorId) external view returns (address);\\n    function treasury(IProduct product) external view returns (address);\\n}\\n\",\"keccak256\":\"0xaabd3740f2265499eea7aad9bd94f9892f53241e5dccce9a50c0e43ed2a6a7cc\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IIncentivizer.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./types/ProgramInfo.sol\\\";\\nimport \\\"./IController.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IIncentivizer {\\n    event ProgramCreated(IProduct indexed product, uint256 indexed programId, ProgramInfo programInfo, UFixed18 programFeeAmount);\\n    event ProgramStarted(IProduct indexed product, uint256 indexed programId, uint256 version);\\n    event ProgramComplete(IProduct indexed product, uint256 indexed programId, uint256 version);\\n    event Claim(IProduct indexed product, address indexed account, uint256 indexed programId, UFixed18 amount);\\n    event FeeClaim(Token18 indexed token, UFixed18 amount);\\n\\n    error IncentivizerNotAllowedError(IProduct product);\\n    error IncentivizerTooManyProgramsError();\\n    error IncentivizerNotProgramOwnerError(IProduct product, uint256 programId);\\n    error IncentivizerInvalidProgramError(IProduct product, uint256 programId);\\n    error IncentivizerBatchClaimArgumentMismatchError();\\n\\n    function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory);\\n    function fees(Token18 token) external view returns (UFixed18);\\n    function initialize(IController controller_) external;\\n    function create(IProduct product, ProgramInfo calldata info) external returns (uint256);\\n    function complete(IProduct product, uint256 programId) external;\\n    function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external;\\n    function syncAccount(address account, IOracleProvider.OracleVersion memory currentOracleVersion) external;\\n    function claim(IProduct product, uint256[] calldata programIds) external;\\n    function claim(IProduct[] calldata products, uint256[][] calldata programIds) external;\\n    function claimFee(Token18[] calldata tokens) external;\\n    function active(IProduct product) external view returns (uint256);\\n    function count(IProduct product) external view returns (uint256);\\n    function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18);\\n    function available(IProduct product, uint256 programId) external view returns (UFixed18);\\n    function versionStarted(IProduct product, uint256 programId) external view returns (uint256);\\n    function versionComplete(IProduct product, uint256 programId) external view returns (uint256);\\n    function owner(IProduct product, uint256 programId) external view returns (address);\\n    function treasury(IProduct product, uint256 programId) external view returns (address);\\n}\\n\",\"keccak256\":\"0x2f95de90dbb3ad35dbfef304f765a622bffff9229868d2898eca8d49c78e8c2c\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IParamProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\\\";\\n\\ninterface IParamProvider {\\n    event MaintenanceUpdated(UFixed18 newMaintenance);\\n    event FundingFeeUpdated(UFixed18 newFundingFee);\\n    event MakerFeeUpdated(UFixed18 newMakerFee);\\n    event TakerFeeUpdated(UFixed18 newTakerFee);\\n    event MakerLimitUpdated(UFixed18 newMakerLimit);\\n    event JumpRateUtilizationCurveUpdated(\\n        Fixed18 minRate,\\n        Fixed18 maxRate,\\n        Fixed18 targetRate,\\n        UFixed18 targetUtilization\\n    );\\n\\n    error ParamProviderInvalidMakerFee();\\n    error ParamProviderInvalidTakerFee();\\n    error ParamProviderInvalidFundingFee();\\n    \\n    function maintenance() external view returns (UFixed18);\\n    function updateMaintenance(UFixed18 newMaintenance) external;\\n    function fundingFee() external view returns (UFixed18);\\n    function updateFundingFee(UFixed18 newFundingFee) external;\\n    function makerFee() external view returns (UFixed18);\\n    function updateMakerFee(UFixed18 newMakerFee) external;\\n    function takerFee() external view returns (UFixed18);\\n    function updateTakerFee(UFixed18 newTakerFee) external;\\n    function makerLimit() external view returns (UFixed18);\\n    function updateMakerLimit(UFixed18 newMakerLimit) external;\\n    function utilizationCurve() external view returns (JumpRateUtilizationCurve memory);\\n    function updateUtilizationCurve(JumpRateUtilizationCurve memory newUtilizationCurve) external;\\n}\\n\",\"keccak256\":\"0x2e2d40d0cf55f167118867e41f740b9b40614d05da50fc9bc33a8cede3eaf03e\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IPayoffProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\n\\ninterface IPayoffProvider {\\n    error PayoffProviderInvalidOracle();\\n    error PayoffProviderInvalidPayoffDefinitionError();\\n\\n    function oracle() external view returns (IOracleProvider);\\n    function payoffDefinition() external view returns (PayoffDefinition memory);\\n    function currentVersion() external view returns (IOracleProvider.OracleVersion memory);\\n    function atVersion(uint256 oracleVersion) external view returns (IOracleProvider.OracleVersion memory);\\n}\\n\",\"keccak256\":\"0xb83d80d624aa9431763f80ecb4bf0214803e25334a7419d954f929e5d0ee7467\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IPerennialLens.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IController.sol\\\";\\n\\n/**\\n * @title Lens contract to conveniently pull protocol, product, and userproduct data\\n * @notice All functions should be called using `callStatic`\\n */\\ninterface IPerennialLens {\\n    /// @dev Snapshot of Product information\\n    struct ProductSnapshot {\\n        IProduct.ProductInfo productInfo;\\n        address productAddress;\\n        Fixed18 rate;\\n        Fixed18 dailyRate;\\n        IOracleProvider.OracleVersion latestVersion;\\n        UFixed18 maintenance;\\n        UFixed18 collateral;\\n        UFixed18 shortfall;\\n        PrePosition pre;\\n        Position position;\\n        UFixed18 productFee;\\n        UFixed18 protocolFee;\\n        Position openInterest;\\n    }\\n\\n    /// @dev Snapshot of User state for a Product\\n    struct UserProductSnapshot {\\n        address productAddress;\\n        address userAddress;\\n        UFixed18 collateral;\\n        UFixed18 maintenance;\\n        PrePosition pre;\\n        Position position;\\n        bool liquidatable;\\n        Position openInterest;\\n        UFixed18 fees;\\n        UFixed18 exposure;\\n    }\\n\\n    // Protocol Values\\n    function controller() external view returns (IController);\\n    function collateral() external view returns (ICollateral);\\n\\n    // Snapshot Functions for batch values\\n    function snapshots(IProduct[] calldata productAddresses) external returns (ProductSnapshot[] memory);\\n    function snapshot(IProduct product) external returns (ProductSnapshot memory);\\n    function snapshots(address account, IProduct[] calldata productAddresses) external returns (UserProductSnapshot[] memory);\\n    function snapshot(address account, IProduct product) external returns (UserProductSnapshot memory);\\n\\n    // Product Values\\n    function name(IProduct product) external view returns (string memory);\\n    function symbol(IProduct product) external view returns (string memory);\\n    function info(IProduct product) external view returns (IProduct.ProductInfo memory _info);\\n    function collateral(IProduct product) external returns (UFixed18);\\n    function shortfall(IProduct product) external returns (UFixed18);\\n    function pre(IProduct product) external returns (PrePosition memory);\\n    function fees(IProduct product) external returns (UFixed18 protocolFees, UFixed18 productFees);\\n    function position(IProduct product) external returns (Position memory);\\n    function globalPosition(IProduct product) external returns (PrePosition memory, Position memory);\\n    function latestVersion(IProduct product) external returns (IOracleProvider.OracleVersion memory);\\n    function atVersions(IProduct product, uint[] memory versions) external returns (IOracleProvider.OracleVersion[] memory prices);\\n    function rate(IProduct product) external returns (Fixed18);\\n    function openInterest(IProduct product) external returns (Position memory);\\n    function dailyRate(IProduct product) external returns (Fixed18);\\n\\n    // UserProduct Values\\n    function collateral(address account, IProduct product) external returns (UFixed18);\\n    function maintenance(address account, IProduct product) external returns (UFixed18);\\n    function liquidatable(address account, IProduct product) external returns (bool);\\n    function pre(address account, IProduct product) external returns (PrePosition memory);\\n    function position(address account, IProduct product) external returns (Position memory);\\n    function userPosition(address account, IProduct product) external returns (PrePosition memory, Position memory);\\n    function fees(address account, IProduct product) external returns (UFixed18);\\n    function openInterest(address account, IProduct product) external returns (Position memory);\\n    function exposure(address account, IProduct product) external returns (UFixed18);\\n    function maintenanceRequired(\\n        address account,\\n        IProduct product,\\n        UFixed18 positionSize\\n    ) external returns (UFixed18);\\n    function unclaimedIncentiveRewards(address account, IProduct product)\\n        external\\n        returns (Token18[] memory tokens, UFixed18[] memory amounts);\\n    function unclaimedIncentiveRewards(\\n        address account,\\n        IProduct product,\\n        uint256[] calldata programIds\\n    ) external returns (Token18[] memory tokens, UFixed18[] memory amounts);\\n}\\n\",\"keccak256\":\"0x64c8a3d6ce3f0ffd0e48bdf694f00d715b147ad481e472fb8206190c6a1e8671\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IProduct.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/curve/types/JumpRateUtilizationCurve.sol\\\";\\nimport \\\"./IPayoffProvider.sol\\\";\\nimport \\\"./IParamProvider.sol\\\";\\nimport \\\"./types/PayoffDefinition.sol\\\";\\nimport \\\"./types/Position.sol\\\";\\nimport \\\"./types/PrePosition.sol\\\";\\nimport \\\"./types/Accumulator.sol\\\";\\n\\ninterface IProduct is IPayoffProvider, IParamProvider {\\n    /// @dev Product Creation parameters\\n    struct ProductInfo {\\n        /// @dev name of the product\\n        string name;\\n\\n        /// @dev symbol of the product\\n        string symbol;\\n\\n        /// @dev product payoff definition\\n        PayoffDefinition payoffDefinition;\\n\\n        /// @dev oracle address\\n        IOracleProvider oracle;\\n\\n        /// @dev product maintenance ratio\\n        UFixed18 maintenance;\\n\\n        /// @dev product funding fee\\n        UFixed18 fundingFee;\\n\\n        /// @dev product maker fee\\n        UFixed18 makerFee;\\n\\n        /// @dev product taker fee\\n        UFixed18 takerFee;\\n\\n        /// @dev product maker limit\\n        UFixed18 makerLimit;\\n\\n        /// @dev utulization curve definition\\n        JumpRateUtilizationCurve utilizationCurve;\\n    }\\n\\n    event Settle(uint256 preVersion, uint256 toVersion);\\n    event AccountSettle(address indexed account, uint256 preVersion, uint256 toVersion);\\n    event MakeOpened(address indexed account, uint256 version, UFixed18 amount);\\n    event TakeOpened(address indexed account, uint256 version, UFixed18 amount);\\n    event MakeClosed(address indexed account, uint256 version, UFixed18 amount);\\n    event TakeClosed(address indexed account, uint256 version, UFixed18 amount);\\n    event ClosedUpdated(bool indexed newClosed, uint256 version);\\n\\n    error ProductInsufficientLiquidityError(UFixed18 socializationFactor);\\n    error ProductDoubleSidedError();\\n    error ProductOverClosedError();\\n    error ProductInsufficientCollateralError();\\n    error ProductInLiquidationError();\\n    error ProductMakerOverLimitError();\\n    error ProductOracleBootstrappingError();\\n    error ProductNotOwnerError();\\n    error ProductInvalidOracle();\\n    error ProductClosedError();\\n\\n    function name() external view returns (string memory);\\n    function symbol() external view returns (string memory);\\n    function initialize(ProductInfo calldata productInfo_) external;\\n    function settle() external;\\n    function settleAccount(address account) external;\\n    function openTake(UFixed18 amount) external;\\n    function closeTake(UFixed18 amount) external;\\n    function openMake(UFixed18 amount) external;\\n    function closeMake(UFixed18 amount) external;\\n    function closeAll(address account) external;\\n    function maintenance(address account) external view returns (UFixed18);\\n    function maintenanceNext(address account) external view returns (UFixed18);\\n    function isClosed(address account) external view returns (bool);\\n    function isLiquidating(address account) external view returns (bool);\\n    function position(address account) external view returns (Position memory);\\n    function pre(address account) external view returns (PrePosition memory);\\n    function latestVersion() external view returns (uint256);\\n    function positionAtVersion(uint256 oracleVersion) external view returns (Position memory);\\n    function pre() external view returns (PrePosition memory);\\n    function valueAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\\n    function shareAtVersion(uint256 oracleVersion) external view returns (Accumulator memory);\\n    function latestVersion(address account) external view returns (uint256);\\n    function rate(Position memory position) external view returns (Fixed18);\\n    function closed() external view returns (bool);\\n    function updateClosed(bool newClosed) external;\\n}\\n\",\"keccak256\":\"0xe1e80b818eadf4cdb070362e40c7cf3863b50c4f944816af27848e319f587241\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/Accumulator.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/Fixed18.sol\\\";\\nimport \\\"./PackedAccumulator.sol\\\";\\n\\n/// @dev Accumulator type\\nstruct Accumulator {\\n    /// @dev maker accumulator per share\\n    Fixed18 maker;\\n    /// @dev taker accumulator per share\\n    Fixed18 taker;\\n}\\nusing AccumulatorLib for Accumulator global;\\n\\n/**\\n * @title AccountAccumulatorLib\\n * @notice Library that surfaces math operations for the Accumulator type.\\n * @dev Accumulators track the cumulative change in position value over time for the maker and taker positions\\n *      respectively. Account-level accumulators can then use two of these values `a` and `a'` to compute the\\n *      change in position value since last sync. This change in value is then used to compute P&L and fees.\\n */\\nlibrary AccumulatorLib {\\n    /**\\n     * @notice Creates a packed accumulator from an accumulator\\n     * @param self an accumulator\\n     * @return New packed accumulator\\n     */\\n    function pack(Accumulator memory self) internal pure returns (PackedAccumulator memory) {\\n        return PackedAccumulator({maker: self.maker.pack(), taker: self.taker.pack()});\\n    }\\n\\n    /**\\n     * @notice Adds two accumulators together\\n     * @param a The first accumulator to sum\\n     * @param b The second accumulator to sum\\n     * @return The resulting summed accumulator\\n     */\\n    function add(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n        return Accumulator({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\\n    }\\n\\n    /**\\n     * @notice Subtracts accumulator `b` from `a`\\n     * @param a The accumulator to subtract from\\n     * @param b The accumulator to subtract\\n     * @return The resulting subtracted accumulator\\n     */\\n    function sub(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n        return Accumulator({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\\n    }\\n\\n    /**\\n     * @notice Multiplies two accumulators together\\n     * @param a The first accumulator to multiply\\n     * @param b The second accumulator to multiply\\n     * @return The resulting multiplied accumulator\\n     */\\n    function mul(Accumulator memory a, Accumulator memory b) internal pure returns (Accumulator memory) {\\n        return Accumulator({maker: a.maker.mul(b.maker), taker: a.taker.mul(b.taker)});\\n    }\\n\\n    /**\\n     * @notice Sums the maker and taker together from a single accumulator\\n     * @param self The struct to operate on\\n     * @return The sum of its maker and taker\\n     */\\n    function sum(Accumulator memory self) internal pure returns (Fixed18) {\\n        return self.maker.add(self.taker);\\n    }\\n}\\n\",\"keccak256\":\"0x7ccd0a72aa593cefb9f4337cf312799f357b82fcb3f0379de0dc503d1cb7e387\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PackedAccumulator.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/PackedFixed18.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\n\\n/// @dev PackedAccumulator type\\nstruct PackedAccumulator {\\n    /// @dev maker accumulator per share\\n    PackedFixed18 maker;\\n    /// @dev taker accumulator per share\\n    PackedFixed18 taker;\\n}\\nusing PackedAccumulatorLib for PackedAccumulator global;\\n\\n/**\\n * @title PackedAccumulatorLib\\n * @dev A packed version of the Accumulator which takes up a single storage slot using `PackedFixed18` values.\\n * @notice Library for the packed Accumulator type.\\n */\\nlibrary PackedAccumulatorLib {\\n    /**\\n     * @notice Creates an accumulator from a packed accumulator\\n     * @param self packed accumulator\\n     * @return New accumulator\\n     */\\n    function unpack(PackedAccumulator memory self) internal pure returns (Accumulator memory) {\\n        return Accumulator({maker: self.maker.unpack(), taker: self.taker.unpack()});\\n    }\\n}\\n\",\"keccak256\":\"0xd83f2822d4f6c818087a232b54007730992c34ff77377fc307a282f886e7cf65\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PackedPosition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/PackedUFixed18.sol\\\";\\nimport \\\"./Position.sol\\\";\\n\\n/// @dev PackedPosition type\\nstruct PackedPosition {\\n    /// @dev Quantity of the maker position\\n    PackedUFixed18 maker;\\n    /// @dev Quantity of the taker position\\n    PackedUFixed18 taker;\\n}\\nusing PackedPositionLib for PackedPosition global;\\n\\n/**\\n * @title PackedPositionLib\\n * @dev A packed version of the Position which takes up a single storage slot using `PackedFixed18` values.\\n * @notice Library for the packed Position type.\\n */\\nlibrary PackedPositionLib {\\n    /**\\n     * @notice Creates an position from a packed position\\n     * @param self packed position\\n     * @return New position\\n     */\\n    function unpack(PackedPosition memory self) internal pure returns (Position memory) {\\n        return Position({maker: self.maker.unpack(), taker: self.taker.unpack()});\\n    }\\n}\\n\",\"keccak256\":\"0x04968e6794f6244cb3415cea111d640273a81faea957872988d0cb580f45df1e\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PayoffDefinition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../../interfaces/IContractPayoffProvider.sol\\\";\\n\\n/// @dev PayoffDefinition tyoe\\nstruct PayoffDefinition {\\n  PayoffDefinitionLib.PayoffType payoffType;\\n  PayoffDefinitionLib.PayoffDirection payoffDirection;\\n  bytes30 data;\\n}\\nusing PayoffDefinitionLib for PayoffDefinition global;\\ntype PayoffDefinitionStorage is bytes32;\\nusing PayoffDefinitionStorageLib for PayoffDefinitionStorage global;\\n\\n/**\\n * @title PayoffDefinitionLib\\n * @dev Library that surfaces logic for PayoffDefinition type functionality\\n * @notice Library for the PayoffDefinition type. Performs validity and price transformation\\n            based on the payoff definition type.\\n */\\nlibrary PayoffDefinitionLib {\\n  using Address for address;\\n\\n  error PayoffDefinitionUnsupportedTransform(PayoffType payoffType, PayoffDirection payoffDirection);\\n  error PayoffDefinitionNotContract(PayoffType payoffType, bytes30 data);\\n\\n  /// @dev Payoff function type enum\\n  enum PayoffType { PASSTHROUGH, CONTRACT }\\n  enum PayoffDirection { LONG, SHORT }\\n\\n  /**\\n   * @notice Checks validity of the payoff definition\\n   * @param self a payoff definition\\n   * @return Whether the payoff definition is valid for it's given type\\n   */\\n  function valid(PayoffDefinition memory self) internal view returns (bool) {\\n    if (self.payoffType == PayoffType.CONTRACT) return address(_providerContract(self)).isContract();\\n\\n    // All other payoff types should have no data\\n    return uint(bytes32(self.data)) == 0;\\n  }\\n\\n  /**\\n   * @notice Transforms a price based on the payoff definition\\n   * @param self a payoff definition\\n   * @param price raw oracle price\\n   * @return Price transformed by the payoff definition function\\n   */\\n  function transform(\\n    PayoffDefinition memory self,\\n    Fixed18 price\\n  ) internal view returns (Fixed18) {\\n    PayoffType payoffType = self.payoffType;\\n    PayoffDirection payoffDirection = self.payoffDirection;\\n    Fixed18 transformedPrice;\\n\\n    // First get the price depending on the type\\n    if (payoffType == PayoffType.PASSTHROUGH) transformedPrice = price;\\n    else if (payoffType == PayoffType.CONTRACT) transformedPrice =  _payoffFromContract(self, price);\\n    else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\\n\\n    // Then transform it depending on the direction flag\\n    if (self.payoffDirection == PayoffDirection.LONG) return transformedPrice;\\n    else if (self.payoffDirection == PayoffDirection.SHORT) return transformedPrice.mul(Fixed18Lib.NEG_ONE);\\n    else revert PayoffDefinitionUnsupportedTransform(payoffType, payoffDirection);\\n  }\\n\\n  /**\\n   * @notice Parses the data field into an address\\n   * @dev Reverts if payoffType is not CONTRACT\\n   * @param self a payoff definition\\n   * @return IContractPayoffProvider address\\n   */\\n  function _providerContract(\\n    PayoffDefinition memory self\\n  ) private pure returns (IContractPayoffProvider) {\\n    if (self.payoffType != PayoffType.CONTRACT) revert PayoffDefinitionNotContract(self.payoffType, self.data);\\n    // Shift to pull the last 20 bytes, then cast to an address\\n    return IContractPayoffProvider(address(bytes20(self.data << 80)));\\n  }\\n\\n  /**\\n   * @notice Performs a price transformation by calling the underlying payoff contract\\n   * @param self a payoff definition\\n   * @param price raw oracle price\\n   * @return Price transformed by the payoff definition function on the contract\\n   */\\n  function _payoffFromContract(\\n    PayoffDefinition memory self,\\n    Fixed18 price\\n  ) private view returns (Fixed18) {\\n    bytes memory ret = address(_providerContract(self)).functionStaticCall(\\n      abi.encodeCall(IContractPayoffProvider.payoff, price)\\n    );\\n    return Fixed18.wrap(abi.decode(ret, (int256)));\\n  }\\n}\\n\\n/**\\n * @title PayoffDefinitionStorageLib\\n * @notice Library that surfaces storage read and writes for the PayoffDefinition type\\n */\\nlibrary PayoffDefinitionStorageLib {\\n    function read(PayoffDefinitionStorage self) internal view returns (PayoffDefinition memory) {\\n        return _storagePointer(self);\\n    }\\n\\n    function store(PayoffDefinitionStorage self, PayoffDefinition memory value) internal {\\n        PayoffDefinition storage storagePointer = _storagePointer(self);\\n\\n        storagePointer.payoffType = value.payoffType;\\n        storagePointer.payoffDirection = value.payoffDirection;\\n        storagePointer.data = value.data;\\n    }\\n\\n    function _storagePointer(\\n      PayoffDefinitionStorage self\\n    ) private pure returns (PayoffDefinition storage pointer) {\\n        assembly { pointer.slot := self }\\n    }\\n}\\n\",\"keccak256\":\"0x4d3897f408f77381c5ae9990391465c8fd511ddf6ff3b39f6cb69d8c2bd554df\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/Position.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\nimport \\\"./PrePosition.sol\\\";\\nimport \\\"./PackedPosition.sol\\\";\\n\\n/// @dev Position type\\nstruct Position {\\n    /// @dev Quantity of the maker position\\n    UFixed18 maker;\\n    /// @dev Quantity of the taker position\\n    UFixed18 taker;\\n}\\nusing PositionLib for Position global;\\n\\n/**\\n * @title PositionLib\\n * @notice Library that surfaces math and settlement computations for the Position type.\\n * @dev Positions track the current quantity of the account's maker and taker positions respectively\\n *      denominated as a unit of the product's payoff function.\\n */\\nlibrary PositionLib {\\n    /**\\n     * @notice Creates a packed position from an position\\n     * @param self A position\\n     * @return New packed position\\n     */\\n    function pack(Position memory self) internal pure returns (PackedPosition memory) {\\n        return PackedPosition({maker: self.maker.pack(), taker: self.taker.pack()});\\n    }\\n\\n    /**\\n     * @notice Returns whether the position is fully empty\\n     * @param self A position\\n     * @return Whether the position is empty\\n     */\\n    function isEmpty(Position memory self) internal pure returns (bool) {\\n        return self.maker.isZero() && self.taker.isZero();\\n    }\\n\\n    /**\\n     * @notice Adds position `a` and `b` together, returning the result\\n     * @param a The first position to sum\\n     * @param b The second position to sum\\n     * @return Resulting summed position\\n     */\\n    function add(Position memory a, Position memory b) internal pure returns (Position memory) {\\n        return Position({maker: a.maker.add(b.maker), taker: a.taker.add(b.taker)});\\n    }\\n\\n    /**\\n     * @notice Subtracts position `b` from `a`, returning the result\\n     * @param a The position to subtract from\\n     * @param b The position to subtract\\n     * @return Resulting subtracted position\\n     */\\n    function sub(Position memory a, Position memory b) internal pure returns (Position memory) {\\n        return Position({maker: a.maker.sub(b.maker), taker: a.taker.sub(b.taker)});\\n    }\\n\\n    /**\\n     * @notice Multiplies position `self` by accumulator `accumulator` and returns the resulting accumulator\\n     * @param self The Position to operate on\\n     * @param accumulator The accumulator to multiply by\\n     * @return Resulting multiplied accumulator\\n     */\\n    function mul(Position memory self, Accumulator memory accumulator) internal pure returns (Accumulator memory) {\\n        return Accumulator({\\n            maker: Fixed18Lib.from(self.maker).mul(accumulator.maker),\\n            taker: Fixed18Lib.from(self.taker).mul(accumulator.taker)\\n        });\\n    }\\n\\n    /**\\n     * @notice Scales position `self` by fixed-decimal `scale` and returns the resulting position\\n     * @param self The Position to operate on\\n     * @param scale The Fixed-decimal to scale by\\n     * @return Resulting scaled position\\n     */\\n    function mul(Position memory self, UFixed18 scale) internal pure returns (Position memory) {\\n        return Position({maker: self.maker.mul(scale), taker: self.taker.mul(scale)});\\n    }\\n\\n    /**\\n     * @notice Divides position `self` by `b` and returns the resulting accumulator\\n     * @param self The Position to operate on\\n     * @param b The number to divide by\\n     * @return Resulting divided accumulator\\n     */\\n    function div(Position memory self, uint256 b) internal pure returns (Accumulator memory) {\\n        return Accumulator({\\n            maker: Fixed18Lib.from(self.maker).div(Fixed18Lib.from(UFixed18Lib.from(b))),\\n            taker: Fixed18Lib.from(self.taker).div(Fixed18Lib.from(UFixed18Lib.from(b)))\\n        });\\n    }\\n\\n    /**\\n     * @notice Returns the maximum of `self`'s maker and taker values\\n     * @param self The struct to operate on\\n     * @return Resulting maximum value\\n     */\\n    function max(Position memory self) internal pure returns (UFixed18) {\\n        return UFixed18Lib.max(self.maker, self.taker);\\n    }\\n\\n    /**\\n     * @notice Sums the maker and taker together from a single position\\n     * @param self The struct to operate on\\n     * @return The sum of its maker and taker\\n     */\\n    function sum(Position memory self) internal pure returns (UFixed18) {\\n        return self.maker.add(self.taker);\\n    }\\n\\n    /**\\n     * @notice Computes the next position after the pending-settlement position delta is included\\n     * @param self The current Position\\n     * @param pre The pending-settlement position delta\\n     * @return Next Position\\n     */\\n    function next(Position memory self, PrePosition memory pre) internal pure returns (Position memory) {\\n        return sub(add(self, pre.openPosition), pre.closePosition);\\n    }\\n\\n    /**\\n     * @notice Returns the settled position at oracle version `toOracleVersion`\\n     * @dev Checks if a new position is ready to be settled based on the provided `toOracleVersion`\\n     *      and `pre` and returns accordingly\\n     * @param self The current Position\\n     * @param pre The pending-settlement position delta\\n     * @param toOracleVersion The oracle version to settle to\\n     * @return Settled position at oracle version\\n     * @return Fee accrued from opening or closing the position\\n     * @return Whether a new position was settled\\n     */\\n    function settled(\\n        Position memory self,\\n        PrePosition memory pre,\\n        IOracleProvider.OracleVersion memory toOracleVersion\\n    ) internal view returns (Position memory, UFixed18, bool) {\\n        return pre.canSettle(toOracleVersion) ? (next(self, pre), pre.computeFee(toOracleVersion), true) : (self, UFixed18Lib.ZERO, false);\\n    }\\n\\n    /**\\n     * @notice Returns the socialization factor for the current position\\n     * @dev Socialization account for the case where `taker` > `maker` temporarily due to a liquidation\\n     *      on the maker side. This dampens the taker's exposure pro-rata to ensure that the maker side\\n     *      is never exposed over 1 x short.\\n     * @param self The Position to operate on\\n     * @return Socialization factor\\n     */\\n    function socializationFactor(Position memory self) internal pure returns (UFixed18) {\\n        return self.taker.isZero() ? UFixed18Lib.ONE : UFixed18Lib.min(UFixed18Lib.ONE, self.maker.div(self.taker));\\n    }\\n}\\n\",\"keccak256\":\"0x027fe392c4f56bf012ba2ca462fcf23e69f2c3b9d283c14089771813437af991\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PrePosition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/perennial-oracle/contracts/interfaces/IOracleProvider.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\n\\n/// @dev PrePosition type\\nstruct PrePosition {\\n    /// @dev Oracle version at which the new position delta was recorded\\n    uint256 oracleVersion;\\n\\n    /// @dev Size of position to open at oracle version\\n    Position openPosition;\\n\\n    /// @dev Size of position to close at oracle version\\n    Position closePosition;\\n}\\nusing PrePositionLib for PrePosition global;\\n\\n/**\\n * @title PrePositionLib\\n * @notice Library that manages a pre-settlement position delta.\\n * @dev PrePositions track the currently awaiting-settlement deltas to a settled Position. These are\\n *      Primarily necessary to introduce lag into the settlement system such that oracle lag cannot be\\n *      gamed to a user's advantage. When a user opens or closes a new position, it sits as a PrePosition\\n *      for one oracle version until it's settle into the Position, making it then effective. PrePositions\\n *      are automatically settled at the correct oracle version even if a flywheel call doesn't happen until\\n *      several version into the future by using the historical version lookups in the corresponding \\\"Versioned\\\"\\n *      global state types.\\n */\\nlibrary PrePositionLib {\\n    /**\\n     * @notice Returns whether there is no pending-settlement position delta\\n     * @dev Can be \\\"empty\\\" even with a non-zero oracleVersion if a position is opened and\\n     *      closed in the same version netting out to a zero position delta\\n     * @param self The struct to operate on\\n     * @return Whether the pending-settlement position delta is empty\\n     */\\n    function isEmpty(PrePosition memory self) internal pure returns (bool) {\\n        return self.openPosition.isEmpty() && self.closePosition.isEmpty();\\n    }\\n\\n    /**\\n     * @notice Increments the maker side of the open position delta\\n     * @dev Nets out open and close deltas to minimize the size of each\\n     * @param self The struct to operate on\\n     * @param currentVersion The current oracle version index\\n     * @param amount The position amount to open\\n     */\\n    function openMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n        self.openPosition.maker = self.openPosition.maker.add(amount);\\n        self.oracleVersion = currentVersion;\\n        _netMake(self);\\n    }\\n\\n    /**\\n     * @notice Increments the maker side of the close position delta\\n     * @dev Nets out open and close deltas to minimize the size of each\\n     * @param self The struct to operate on\\n     * @param currentVersion The current oracle version index\\n     * @param amount The maker position amount to close\\n     */\\n    function closeMake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n        self.closePosition.maker = self.closePosition.maker.add(amount);\\n        self.oracleVersion = currentVersion;\\n        _netMake(self);\\n    }\\n\\n    /**\\n     * @notice Increments the taker side of the open position delta\\n     * @dev Nets out open and close deltas to minimize the size of each\\n     * @param self The struct to operate on\\n     * @param currentVersion The current oracle version index\\n     * @param amount The taker position amount to open\\n     */\\n    function openTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n        self.openPosition.taker = self.openPosition.taker.add(amount);\\n        self.oracleVersion = currentVersion;\\n        _netTake(self);\\n    }\\n\\n    /**\\n     * @notice Increments the taker side of the close position delta\\n     * @dev Nets out open and close deltas to minimize the size of each\\n     * @param self The struct to operate on\\n     * @param currentVersion The current oracle version index\\n     * @param amount The taker position amount to close\\n     */\\n    function closeTake(PrePosition storage self, uint256 currentVersion, UFixed18 amount) internal {\\n        self.closePosition.taker = self.closePosition.taker.add(amount);\\n        self.oracleVersion = currentVersion;\\n        _netTake(self);\\n    }\\n\\n    /**\\n     * @notice Nets out the open and close on the maker side of the position delta\\n     * @param self The struct to operate on\\n     */\\n    function _netMake(PrePosition storage self) private {\\n        if (self.openPosition.maker.gt(self.closePosition.maker)) {\\n            self.openPosition.maker = self.openPosition.maker.sub(self.closePosition.maker);\\n            self.closePosition.maker = UFixed18Lib.ZERO;\\n        } else {\\n            self.closePosition.maker = self.closePosition.maker.sub(self.openPosition.maker);\\n            self.openPosition.maker = UFixed18Lib.ZERO;\\n        }\\n    }\\n\\n    /**\\n     * @notice Nets out the open and close on the taker side of the position delta\\n     * @param self The struct to operate on\\n     */\\n    function _netTake(PrePosition storage self) private {\\n        if (self.openPosition.taker.gt(self.closePosition.taker)) {\\n            self.openPosition.taker = self.openPosition.taker.sub(self.closePosition.taker);\\n            self.closePosition.taker = UFixed18Lib.ZERO;\\n        } else {\\n            self.closePosition.taker = self.closePosition.taker.sub(self.openPosition.taker);\\n            self.openPosition.taker = UFixed18Lib.ZERO;\\n        }\\n    }\\n\\n    /**\\n     * @notice Returns whether the the pending position delta can be settled at version `toOracleVersion`\\n     * @dev Pending-settlement positions deltas can be settled (1) oracle version after they are recorded\\n     * @param self The struct to operate on\\n     * @param toOracleVersion The potential oracle version to settle\\n     * @return Whether the position delta can be settled\\n     */\\n    function canSettle(\\n        PrePosition memory self,\\n        IOracleProvider.OracleVersion memory toOracleVersion\\n    ) internal pure returns (bool) {\\n        return !isEmpty(self) && toOracleVersion.version > self.oracleVersion;\\n    }\\n\\n    /**\\n     * @notice Computes the fee incurred for opening or closing the pending-settlement position\\n     * @dev Must be called from a valid product to get the proper fee amounts\\n     * @param self The struct to operate on\\n     * @param toOracleVersion The oracle version at which settlement takes place\\n     * @return positionFee The maker / taker fee incurred\\n     */\\n    function computeFee(\\n        PrePosition memory self,\\n        IOracleProvider.OracleVersion memory toOracleVersion\\n    ) internal view returns (UFixed18) {\\n        Position memory positionDelta = self.openPosition.add(self.closePosition);\\n\\n        (UFixed18 makerNotional, UFixed18 takerNotional) = (\\n            Fixed18Lib.from(positionDelta.maker).mul(toOracleVersion.price).abs(),\\n            Fixed18Lib.from(positionDelta.taker).mul(toOracleVersion.price).abs()\\n        );\\n\\n        IProduct product = IProduct(address(this));\\n        return makerNotional.mul(product.makerFee()).add(takerNotional.mul(product.takerFee()));\\n    }\\n\\n    /**\\n     * @notice Computes the next oracle version to settle\\n     * @dev - If there is no pending-settlement position delta, returns the current oracle version\\n     *      - Otherwise returns the oracle version at which the pending-settlement position delta can be first settled\\n     *\\n     *      Corresponds to point (b) in the Position settlement flow\\n     * @param self The struct to operate on\\n     * @param currentVersion The current oracle version index\\n     * @return Next oracle version to settle\\n     */\\n    function settleVersion(PrePosition storage self, uint256 currentVersion) internal view returns (uint256) {\\n        uint256 _oracleVersion = self.oracleVersion;\\n        return _oracleVersion == 0 ? currentVersion : _oracleVersion + 1;\\n    }\\n}\\n\",\"keccak256\":\"0xa6f83f7b5f8139ec874235c406debd086a152977493c08b7f280df6f1737fb96\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/ProgramInfo.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"../IProduct.sol\\\";\\nimport \\\"./Position.sol\\\";\\nimport \\\"./Accumulator.sol\\\";\\n\\n/// @dev ProgramInfo type\\nstruct ProgramInfo {\\n    /// @dev Coordinator for this program\\n    uint256 coordinatorId;\\n\\n    /// @dev Amount of total maker and taker rewards\\n    Position amount;\\n\\n    /// @dev start timestamp of the program\\n    uint256 start;\\n\\n    /// @dev duration of the program (in seconds)\\n    uint256 duration;\\n\\n    /**\\n     * @dev Reward ERC20 token contract\\n     * @notice Perennial does not support non-standard ERC20s as reward tokens for incentive programs, including,\\n                but not limited to: fee on transfer and rebase tokens. Using such a non-standard token will likely\\n                result in loss of funds.\\n     */\\n    Token18 token;\\n}\\nusing ProgramInfoLib for ProgramInfo global;\\n\\n/**\\n * @title ProgramInfoLib\\n * @notice Library that snapshots the static information for a single program.\\n * @dev This information does not change during the operation of a program.\\n */\\nlibrary ProgramInfoLib {\\n    uint256 private constant MIN_DURATION = 1 days;\\n    uint256 private constant MAX_DURATION = 2 * 365 days;\\n\\n    error ProgramInvalidStartError();\\n    error ProgramInvalidDurationError();\\n\\n    /**\\n     * @notice Validates and creates a new Program\\n     * @dev Reverts for invalid programInfos\\n     * @param programInfo Un-sanitized static program information\\n     */\\n    function validate(ProgramInfo memory programInfo) internal view {\\n        if (isStarted(programInfo, block.timestamp)) revert ProgramInvalidStartError();\\n        if (programInfo.duration < MIN_DURATION || programInfo.duration > MAX_DURATION) revert ProgramInvalidDurationError();\\n    }\\n\\n    /**\\n     * @notice Computes a new program info with the fee taken out of the amount\\n     * @param programInfo Original program info\\n     * @param incentivizationFee The incentivization fee\\n     * @return New program info\\n     * @return Fee amount\\n     */\\n    function deductFee(ProgramInfo memory programInfo, UFixed18 incentivizationFee)\\n    internal pure returns (ProgramInfo memory, UFixed18) {\\n        Position memory newProgramAmount = programInfo.amount.mul(UFixed18Lib.ONE.sub(incentivizationFee));\\n        UFixed18 programFeeAmount = programInfo.amount.sub(newProgramAmount).sum();\\n        programInfo.amount = newProgramAmount;\\n        return (programInfo, programFeeAmount);\\n    }\\n\\n    /**\\n     * @notice Returns the maker and taker amounts per position share\\n     * @param self The ProgramInfo to operate on\\n     * @return programFee Amounts per share\\n     */\\n    function amountPerShare(ProgramInfo memory self) internal pure returns (Accumulator memory) {\\n        return self.amount.div(self.duration);\\n    }\\n\\n    /**\\n     * @notice Returns whether the program has started by timestamp `timestamp`\\n     * @param self The ProgramInfo to operate on\\n     * @param timestamp Timestamp to check for\\n     * @return Whether the program has started\\n     */\\n    function isStarted(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\\n        return timestamp >= self.start;\\n    }\\n\\n    /**\\n     * @notice Returns whether the program is completed by timestamp `timestamp`\\n     * @param self The ProgramInfo to operate on\\n     * @param timestamp Timestamp to check for\\n     * @return Whether the program is completed\\n     */\\n    function isComplete(ProgramInfo memory self, uint256 timestamp) internal pure returns (bool) {\\n        return timestamp >= (self.start + self.duration);\\n    }\\n}\\n\",\"keccak256\":\"0x280fcaf931b49abaec46b95ccbabaaf856a4b8e8d036413c9c3b3af25585d161\",\"license\":\"Apache-2.0\"},\"contracts/lens/PerennialLens.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"../interfaces/IPerennialLens.sol\\\";\\n\\n/**\\n * @title Lens contract to conveniently pull protocol data\\n * @notice All functions should be called using `callStatic`\\n */\\ncontract PerennialLens is IPerennialLens {\\n    /**\\n     * @notice Protocol controller\\n     * @return Protocol controller\\n     */\\n    IController public immutable controller;\\n\\n    /// @param _controller Protocol controller address\\n    constructor(IController _controller) {\\n        controller = _controller;\\n    }\\n\\n    /**\\n     * @notice Protocol collateral address\\n     * @return Protocol collateral address\\n     */\\n    function collateral() public view returns (ICollateral) {\\n        return controller.collateral();\\n    }\\n\\n    /**\\n     *  Snapshot Functions\\n     */\\n\\n    /**\\n     * @notice Returns the snapshots of the provided `productAddresses`\\n     * @param productAddresses Product addresses\\n     * @return Snapshot for each product after settle\\n     */\\n    function snapshots(IProduct[] calldata productAddresses) public returns (ProductSnapshot[] memory) {\\n        ProductSnapshot[] memory _snapshots = new ProductSnapshot[](productAddresses.length);\\n        for (uint256 i = 0; i < productAddresses.length; i++) {\\n            _snapshots[i] = snapshot(productAddresses[i]);\\n        }\\n\\n        return _snapshots;\\n    }\\n\\n    /**\\n     * @notice Returns the snapshot of the provided `product`\\n     * @param product Product address\\n     * @return Snapshot for the product after settle\\n     */\\n    function snapshot(IProduct product) public settle(product) returns (ProductSnapshot memory) {\\n        ProductSnapshot memory _snapshot;\\n\\n        _snapshot.productInfo = info(product);\\n        _snapshot.productAddress = address(product);\\n        _snapshot.rate = rate(product);\\n        _snapshot.dailyRate = dailyRate(product);\\n        _snapshot.latestVersion = latestVersion(product);\\n        _snapshot.maintenance = product.maintenance();\\n        _snapshot.collateral = collateral(product);\\n        _snapshot.shortfall = shortfall(product);\\n        _snapshot.pre = pre(product);\\n        _snapshot.position = position(product);\\n        (UFixed18 productFee, UFixed18 protocolFee) = fees(product);\\n        _snapshot.productFee = productFee;\\n        _snapshot.protocolFee = protocolFee;\\n        _snapshot.openInterest = openInterest(product);\\n\\n        return _snapshot;\\n    }\\n\\n    /**\\n     * @notice Returns the user snapshots for the provided `productAddresses`\\n     * @param account User addresses\\n     * @param productAddresses Product addresses\\n     * @return UserSnapshot for each product after settle\\n     */\\n    function snapshots(address account, IProduct[] memory productAddresses)\\n        public returns (UserProductSnapshot[] memory)\\n    {\\n        UserProductSnapshot[] memory _snapshots = new UserProductSnapshot[](productAddresses.length);\\n        for (uint256 i = 0; i < productAddresses.length; i++) {\\n            _snapshots[i] = snapshot(account, productAddresses[i]);\\n        }\\n\\n        return _snapshots;\\n    }\\n\\n    /**\\n     * @notice Returns the user snapshot for the provided `product`\\n     * @param account User addresses\\n     * @param product Product address\\n     * @return UserSnapshot for the product after settle\\n     */\\n    function snapshot(address account, IProduct product)\\n        public\\n        settleAccount(account, product)\\n        returns (UserProductSnapshot memory)\\n    {\\n        UserProductSnapshot memory _snapshot;\\n\\n        _snapshot.productAddress = address(product);\\n        _snapshot.userAddress = account;\\n        _snapshot.collateral = collateral(account, product);\\n        _snapshot.maintenance = maintenance(account, product);\\n        _snapshot.pre = pre(account, product);\\n        _snapshot.position = position(account, product);\\n        _snapshot.liquidatable = liquidatable(account, product);\\n        _snapshot.openInterest = openInterest(account, product);\\n        _snapshot.fees = fees(account, product);\\n        _snapshot.exposure = exposure(account, product);\\n\\n        return _snapshot;\\n    }\\n\\n    /**\\n     *  End Snapshot Functions\\n     */\\n\\n    /**\\n     *  Product Individual Fields Functions\\n     */\\n\\n    /**\\n     * @notice Returns the name of the provided `product`\\n     * @param product Product address\\n     * @return Name of the product\\n     */\\n    function name(IProduct product) public view returns (string memory) {\\n        return product.name();\\n    }\\n\\n    /**\\n     * @notice Returns the symbol of the provided `product`\\n     * @param product Product address\\n     * @return Symbol of the product\\n     */\\n    function symbol(IProduct product) public view returns (string memory) {\\n        return product.symbol();\\n    }\\n\\n    /**\\n     * @notice Returns the info of the provided `product`\\n     * @param product Product address\\n     * @return _info of the product\\n     */\\n    function info(IProduct product) public view returns (IProduct.ProductInfo memory _info) {\\n        _info.name = name(product);\\n        _info.symbol = symbol(product);\\n        _info.payoffDefinition = product.payoffDefinition();\\n        _info.oracle = product.oracle();\\n        _info.maintenance = product.maintenance();\\n        _info.fundingFee = product.fundingFee();\\n        _info.makerFee = product.makerFee();\\n        _info.takerFee = product.takerFee();\\n        _info.makerLimit = product.makerLimit();\\n        _info.utilizationCurve = product.utilizationCurve();\\n    }\\n\\n    /**\\n     * @notice Product total collateral amount after settle\\n     * @param product Product address\\n     * @return Total collateral for product\\n     */\\n    function collateral(IProduct product) public settle(product) returns (UFixed18) {\\n        return collateral().collateral(product);\\n    }\\n\\n    /**\\n     * @notice Product total shortfall amount after settle\\n     * @param product Product address\\n     * @return Total shortfall for product\\n     */\\n    function shortfall(IProduct product) public settle(product) returns (UFixed18) {\\n        return collateral().shortfall(product);\\n    }\\n\\n    /**\\n     * @notice Product pre position after settle\\n     * @param product Product address\\n     * @return Product pre-position\\n     */\\n    function pre(IProduct product) public settle(product) returns (PrePosition memory) {\\n        return product.pre();\\n    }\\n\\n    /**\\n     * @notice Product position after settle\\n     * @param product Product address\\n     * @return product position\\n     */\\n    function position(IProduct product) public settle(product) returns (Position memory) {\\n        return _latestPosition(product);\\n    }\\n\\n    /**\\n     * @notice Product pre-position and position after settle\\n     * @param product Product address\\n     * @return Product pre-position\\n     * @return Product position\\n     */\\n    function globalPosition(IProduct product) public settle(product) returns (PrePosition memory, Position memory) {\\n        return (product.pre(), _latestPosition(product));\\n    }\\n\\n    /**\\n     * @notice Current price of product after settle\\n     * @param product Product address\\n     * @return Product latest price\\n     */\\n    function latestVersion(IProduct product) public settle(product) returns (IOracleProvider.OracleVersion memory) {\\n        return _latestVersion(product);\\n    }\\n\\n    /**\\n     * @notice Prices of product at specified versions after settle\\n     * @param product Product address\\n     * @param versions Oracle versions to query\\n     * @return prices Product prices at specified versions\\n     */\\n    function atVersions(IProduct product, uint256[] memory versions)\\n        public\\n        settle(product)\\n        returns (IOracleProvider.OracleVersion[] memory prices)\\n    {\\n        prices = new IOracleProvider.OracleVersion[](versions.length);\\n        for (uint256 i = 0; i < versions.length; i++) {\\n            prices[i] = product.atVersion(versions[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Product funding rate after settle\\n     * @param product Product address\\n     * @return Product current funding rate\\n     */\\n    function rate(IProduct product) public settle(product) returns (Fixed18) {\\n        Position memory position_ = _latestPosition(product);\\n        return product.rate(position_);\\n    }\\n\\n    /**\\n     * @notice Product funding extrapolated to a daily rate after settle\\n     * @param product Product address\\n     * @return Product current funding extrapolated to a daily rate\\n     */\\n    function dailyRate(IProduct product) public settle(product) returns (Fixed18) {\\n        Position memory position_ = _latestPosition(product);\\n        return product.rate(position_).mul(Fixed18Lib.from(60 * 60 * 24));\\n    }\\n\\n    /**\\n     * @notice Fees accumulated by product and protocol treasuries after settle\\n     * @param product Product address\\n     * @return protocolFees fees accrued by the protocol\\n     * @return productFees fees accrued by the product owner\\n     */\\n    function fees(IProduct product) public settle(product) returns (UFixed18 protocolFees, UFixed18 productFees) {\\n        address protocolTreasury = controller.treasury();\\n        address productTreasury = controller.treasury(product);\\n\\n        protocolFees = collateral().fees(protocolTreasury);\\n        productFees = collateral().fees(productTreasury);\\n    }\\n\\n    /**\\n     * @notice Product total open interest after settle\\n     * @param product Product address\\n     * @return Product maker and taker position multiplied by latest price after settle\\n     */\\n    function openInterest(IProduct product) public settle(product) returns (Position memory) {\\n        return _latestPosition(product).mul(_latestVersion(product).price.abs());\\n    }\\n\\n    /**\\n     *  End Product Individual Fields Functions\\n     */\\n\\n    /**\\n     *  UserProduct Individual Fields Functions\\n     */\\n\\n    /**\\n     * @notice User collateral amount for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return User deposited collateral for product\\n     */\\n    function collateral(address account, IProduct product) public settleAccount(account, product) returns (UFixed18) {\\n        return collateral().collateral(account, product);\\n    }\\n\\n    /**\\n     * @notice User maintenance amount for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return Maximum of user maintenance, and maintenanceNext\\n     */\\n    function maintenance(address account, IProduct product) public settleAccount(account, product) returns (UFixed18) {\\n        return UFixed18Lib.max(product.maintenance(account), product.maintenanceNext(account));\\n    }\\n\\n    /**\\n     * @notice User liquidatble status for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return Whether or not the user's position eligible to be liquidated\\n     */\\n    function liquidatable(address account, IProduct product) public settleAccount(account, product) returns (bool) {\\n        return collateral().liquidatable(account, product);\\n    }\\n\\n    /**\\n     * @notice User pre position for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return User pre-position\\n     */\\n    function pre(address account, IProduct product)\\n        public\\n        settleAccount(account, product)\\n        returns (PrePosition memory)\\n    {\\n        return product.pre(account);\\n    }\\n\\n    /**\\n     * @notice User position for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return User position\\n     */\\n    function position(address account, IProduct product)\\n        public\\n        settleAccount(account, product)\\n        returns (Position memory)\\n    {\\n        return product.position(account);\\n    }\\n\\n    /**\\n     * @notice User pre-position and position for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return User pre-position\\n     * @return User position\\n     */\\n    function userPosition(address account, IProduct product)\\n        public\\n        settleAccount(account, product)\\n        returns (PrePosition memory, Position memory)\\n    {\\n        return (product.pre(account), product.position(account));\\n    }\\n\\n    /**\\n     * @notice Fees accumulated by account after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return sum of all fees accrued by the account\\n     */\\n    function fees(address account, IProduct product) public settleAccount(account, product) returns (UFixed18) {\\n        return collateral().fees(account);\\n    }\\n\\n    /**\\n     * @notice User's open interest in product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return User's maker or taker position multiplied by latest price after settle\\n     */\\n    function openInterest(address account, IProduct product)\\n        public\\n        settleAccount(account, product)\\n        returns (Position memory)\\n    {\\n        return product.position(account).mul(_latestVersion(product).price.abs());\\n    }\\n\\n    /**\\n     * @notice User's exposure in product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return User's exposure (openInterest * utilization) after settle\\n     */\\n    function exposure(address account, IProduct product) public settleAccount(account, product) returns (UFixed18) {\\n        (, Position memory _pos) = globalPosition(product);\\n        if (_pos.maker.eq(UFixed18Lib.ZERO)) { return UFixed18Lib.ZERO; }\\n\\n        UFixed18 utilization = _pos.taker.div(_pos.maker);\\n        Position memory _openInterest = openInterest(account, product);\\n\\n        return utilization.mul(_openInterest.maker.gte(UFixed18Lib.ZERO) ? _openInterest.maker : _openInterest.taker);\\n    }\\n\\n    /**\\n     * @notice User's maintenance required for position size in product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @param positionSize size of position for maintenance calculation\\n     * @return Maintenance required for position in product\\n     */\\n    function maintenanceRequired(\\n        address account,\\n        IProduct product,\\n        UFixed18 positionSize\\n    ) public settleAccount(account, product) returns (UFixed18) {\\n        UFixed18 notional = positionSize.mul(_latestVersion(product).price.abs());\\n        return notional.mul(product.maintenance());\\n    }\\n\\n    /**\\n     * @notice User's unclaimed rewards for all programs for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @return tokens Token addresses of unclaimed incentive rewards for given product\\n     * @return amounts Token amounts of unclaimed incentive rewards for given product\\n     */\\n    function unclaimedIncentiveRewards(address account, IProduct product)\\n        public\\n        settleAccount(account, product)\\n        returns (Token18[] memory tokens, UFixed18[] memory amounts)\\n    {\\n        IIncentivizer incentivizer = controller.incentivizer();\\n\\n        uint256 programsLength = incentivizer.count(product);\\n        tokens = new Token18[](programsLength);\\n        amounts = new UFixed18[](programsLength);\\n        for (uint256 i = 0; i < programsLength; i++) {\\n            ProgramInfo memory programInfo = incentivizer.programInfos(product, i);\\n            tokens[i] = programInfo.token;\\n            amounts[i] = incentivizer.unclaimed(product, account, i);\\n        }\\n    }\\n\\n    /**\\n     * @notice User's unclaimed rewards for provided programs for product after settle\\n     * @param account Account address\\n     * @param product Product address\\n     * @param programIds Program IDs to query\\n     * @return tokens Token addresses of unclaimed incentive rewards for given program IDs\\n     * @return amounts Token amounts of unclaimed incentive rewards for given program IDs\\n     */\\n    function unclaimedIncentiveRewards(\\n        address account,\\n        IProduct product,\\n        uint256[] calldata programIds\\n    ) public settleAccount(account, product) returns (Token18[] memory tokens, UFixed18[] memory amounts) {\\n        IIncentivizer incentivizer = controller.incentivizer();\\n        tokens = new Token18[](programIds.length);\\n        amounts = new UFixed18[](programIds.length);\\n        for (uint256 i = 0; i < programIds.length; i++) {\\n            ProgramInfo memory programInfo = incentivizer.programInfos(product, programIds[i]);\\n            tokens[i] = programInfo.token;\\n            amounts[i] = incentivizer.unclaimed(product, account, programIds[i]);\\n        }\\n    }\\n\\n    /**\\n     *  End UserProduct Individual Fields Functions\\n     */\\n\\n    /**\\n     *  Private Helper Functions\\n     */\\n\\n    /**\\n     * @notice Returns the Product's latest position\\n     * @dev Private function, does not call settle itself\\n     * @param product Product address\\n     * @return Latest position for the product\\n     */\\n    function _latestPosition(IProduct product) private view returns (Position memory) {\\n        return product.positionAtVersion(product.latestVersion());\\n    }\\n\\n    /**\\n     * @notice Returns the Product's latest version\\n     * @dev Private function, does not call settle itself\\n     * @param product Product address\\n     * @return Latest version for the product\\n     */\\n    function _latestVersion(IProduct product) private view returns (IOracleProvider.OracleVersion memory) {\\n        return product.atVersion(product.latestVersion());\\n    }\\n\\n    /**\\n     *  End Private Helper Functions\\n     */\\n\\n    /**\\n     *  Modifier Functions\\n     */\\n\\n    /// @dev Settles the product\\n    modifier settle(IProduct product) {\\n        product.settle();\\n        _;\\n    }\\n\\n    /// @dev Settles the product. product.settleAccount also settles the product\\n    modifier settleAccount(address account, IProduct product) {\\n        product.settleAccount(account);\\n        _;\\n    }\\n\\n    /**\\n     *  End Modifier Functions\\n     */\\n}\\n\",\"keccak256\":\"0xde79efaa7b24def388ce78eef9384b1328f2157266a73f453299ec34aaaaa324\",\"license\":\"Apache-2.0\"}},\"version\":1}",
  "bytecode": "0x60a06040523480156200001157600080fd5b5060405162005d6738038062005d678339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051615c066200016160003960008181611a360152818161288201528181612ba101528181612c3701528181612f9a015261302d0152615c066000f3fe608060405234801561001057600080fd5b506004361061020b5760003560e01c80638f5edc081161012a578063b7a98f97116100bd578063edd8ca7b1161008c578063f77c479111610071578063f77c4791146107a1578063f8083f56146107bf578063faaebd21146107f05761020b565b8063edd8ca7b14610741578063f5c06e1b146107715761020b565b8063b7a98f9714610693578063cc218ece146106c3578063d8dfeb45146106f3578063e9c6b4c1146107115761020b565b8063a5fdc5de116100f9578063a5fdc5de146105d3578063a86e357614610603578063b4d6f78114610633578063b7648fb9146106635761020b565b80638f5edc08146105135780639b9ac2cb146105435780639bc02857146105735780639be2a567146105a35761020b565b806337e710ac116101a25780637e64cc13116101715780637e64cc131461045257806382df39de146104835780638e076924146104b35780638e480b20146104e35761020b565b806337e710ac14610391578063540027e6146103c15780636878353e146103f15780636efef085146104225761020b565b80631e0c6fb9116101de5780631e0c6fb9146102d1578063204e94b014610301578063237e58991461033157806326512160146103615761020b565b80630198489214610210578063036790c0146102405780630aae7a6b146102715780630ba9d8ca146102a1575b600080fd5b61022a60048036038101906102259190613899565b610821565b604051610237919061395f565b60405180910390f35b61025a60048036038101906102559190613899565b61089e565b604051610268929190613a75565b60405180910390f35b61028b60048036038101906102869190613899565b610991565b6040516102989190613e3c565b60405180910390f35b6102bb60048036038101906102b69190613899565b610dae565b6040516102c89190613e99565b60405180910390f35b6102eb60048036038101906102e69190613899565b610ea1565b6040516102f89190613eb4565b60405180910390f35b61031b60048036038101906103169190613efb565b610f81565b604051610328919061408b565b60405180910390f35b61034b60048036038101906103469190613efb565b611125565b60405161035891906140b6565b60405180910390f35b61037b60048036038101906103769190613899565b611246565b6040516103889190614320565b60405180910390f35b6103ab60048036038101906103a69190613efb565b61142d565b6040516103b891906140b6565b60405180910390f35b6103db60048036038101906103d69190613899565b6115a2565b6040516103e89190613e99565b60405180910390f35b61040b60048036038101906104069190613efb565b6116b2565b604051610419929190613a75565b60405180910390f35b61043c600480360381019061043791906144b6565b61182f565b60405161044991906145c1565b60405180910390f35b61046c60048036038101906104679190613efb565b6119c2565b60405161047a929190614762565b60405180910390f35b61049d60048036038101906104989190613efb565b611d73565b6040516104aa91906147a8565b60405180910390f35b6104cd60048036038101906104c891906147ef565b611e6f565b6040516104da91906140b6565b60405180910390f35b6104fd60048036038101906104f89190613899565b611f96565b60405161050a9190614884565b60405180910390f35b61052d60048036038101906105289190614962565b612010565b60405161053a9190614b52565b60405180910390f35b61055d60048036038101906105589190613efb565b6120d1565b60405161056a91906140b6565b60405180910390f35b61058d60048036038101906105889190614bcf565b6121cb565b60405161059a9190614df9565b60405180910390f35b6105bd60048036038101906105b89190613efb565b61229c565b6040516105ca9190613eb4565b60405180910390f35b6105ed60048036038101906105e89190613899565b612395565b6040516105fa91906140b6565b60405180910390f35b61061d60048036038101906106189190613899565b612481565b60405161062a919061395f565b60405180910390f35b61064d60048036038101906106489190613899565b6124fe565b60405161065a91906140b6565b60405180910390f35b61067d60048036038101906106789190613899565b6125ea565b60405161068a9190614e1b565b60405180910390f35b6106ad60048036038101906106a89190613efb565b612664565b6040516106ba9190614e1b565b60405180910390f35b6106dd60048036038101906106d89190613efb565b612782565b6040516106ea91906140b6565b60405180910390f35b6106fb61287e565b6040516107089190614e57565b60405180910390f35b61072b60048036038101906107269190613efb565b612914565b6040516107389190614e1b565b60405180910390f35b61075b60048036038101906107569190613899565b612a0c565b6040516107689190614e1b565b60405180910390f35b61078b60048036038101906107869190613efb565b612aac565b60405161079891906147a8565b60405180910390f35b6107a9612b9f565b6040516107b69190614e93565b60405180910390f35b6107d960048036038101906107d49190614f04565b612bc3565b6040516107e7929190614762565b60405180910390f35b61080a60048036038101906108059190613899565b612f32565b604051610818929190614f78565b60405180910390f35b60608173ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561086e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906108979190615047565b9050919050565b6108a6613573565b6108ae6135a0565b828073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156108f757600080fd5b505af115801561090b573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff166359ea287d6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561095a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097e9190615173565b610987856131d5565b9250925050915091565b6109996135ba565b6109a282610821565b81600001819052506109b382612481565b81602001819052508173ffffffffffffffffffffffffffffffffffffffff166305d5c1cb6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610a06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2a919061527a565b81604001819052508173ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa191906152e5565b816060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff16636c376cc56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b479190615312565b8160800181815250508173ffffffffffffffffffffffffffffffffffffffff16635d16e1206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbf9190615312565b8160a00181815250508173ffffffffffffffffffffffffffffffffffffffff1663fc741c7c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c379190615312565b8160c00181815250508173ffffffffffffffffffffffffffffffffffffffff166343f0179b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610caf9190615312565b8160e00181815250508173ffffffffffffffffffffffffffffffffffffffff1663193775676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d279190615312565b816101000181815250508173ffffffffffffffffffffffffffffffffffffffff1663a12e1b336040518163ffffffff1660e01b8152600401608060405180830381865afa158015610d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da0919061540f565b816101200181905250919050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610df957600080fd5b505af1158015610e0d573d6000803e3d6000fd5b505050506000610e1c846131d5565b90508373ffffffffffffffffffffffffffffffffffffffff166360ec91d6826040518263ffffffff1660e01b8152600401610e579190614e1b565b602060405180830381865afa158015610e74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e989190615468565b92505050919050565b610ea9613573565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ef257600080fd5b505af1158015610f06573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166359ea287d6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610f55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f799190615173565b915050919050565b610f8961362f565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401610fc491906154a4565b600060405180830381600087803b158015610fde57600080fd5b505af1158015610ff2573d6000803e3d6000fd5b5050505083836000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084836020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506110708585612782565b836040018181525050611083858561142d565b836060018181525050611096858561229c565b83608001819052506110a88585612914565b8360a001819052506110ba8585611d73565b8360c00190151590811515815250506110d38585612aac565b8360e00190151590811515815250506110ec8585612664565b8361010001819052506110ff85856120d1565b836101200181815250506111138585611125565b83610140018181525050505092915050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161116291906154a4565b600060405180830381600087803b15801561117c57600080fd5b505af1158015611190573d6000803e3d6000fd5b5050505060006111a08686612664565b90506111ba600082602001516132cb90919063ffffffff16565b156111cc57806020015193505061123e565b60006111d78661089e565b9150506111f2600082600001516132e290919063ffffffff16565b156112025760009450505061123e565b600061121f826000015183602001516132f990919063ffffffff16565b905061123883600001518261332290919063ffffffff16565b95505050505b505092915050565b61124e6136cb565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561129757600080fd5b505af11580156112ab573d6000803e3d6000fd5b505050506112b883610991565b826000018190525082826020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505061130183610dae565b826040018181525050611313836115a2565b82606001818152505061132583611f96565b82608001819052508273ffffffffffffffffffffffffffffffffffffffff16636c376cc56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190615312565b8260a00181815250506113ae83612395565b8260c00181815250506113c0836124fe565b8260e00181815250506113d283610ea1565b8261010001819052506113e4836125ea565b8261012001819052506000806113f985612f32565b915091508184610140018181525050808461016001818152505061141c85612a0c565b846101800181905250505050919050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161146a91906154a4565b600060405180830381600087803b15801561148457600080fd5b505af1158015611498573d6000803e3d6000fd5b505050506115988473ffffffffffffffffffffffffffffffffffffffff166391689024876040518263ffffffff1660e01b81526004016114d891906154a4565b602060405180830381865afa1580156114f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115199190615312565b8573ffffffffffffffffffffffffffffffffffffffff1663ab582f29886040518263ffffffff1660e01b815260040161155291906154a4565b602060405180830381865afa15801561156f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115939190615312565b61334b565b9250505092915050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156115ed57600080fd5b505af1158015611601573d6000803e3d6000fd5b505050506000611610846131d5565b90506116a96116216201518061335f565b8573ffffffffffffffffffffffffffffffffffffffff166360ec91d6846040518263ffffffff1660e01b815260040161165a9190614e1b565b602060405180830381865afa158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b9190615468565b61337c90919063ffffffff16565b92505050919050565b6116ba613573565b6116c26135a0565b83838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016116fd91906154a4565b600060405180830381600087803b15801561171757600080fd5b505af115801561172b573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff16631e0c6fb9876040518263ffffffff1660e01b815260040161176891906154a4565b60a060405180830381865afa158015611785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a99190615173565b8573ffffffffffffffffffffffffffffffffffffffff1663b7648fb9886040518263ffffffff1660e01b81526004016117e291906154a4565b6040805180830381865afa1580156117fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182291906154bf565b9350935050509250929050565b6060828073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561187a57600080fd5b505af115801561188e573d6000803e3d6000fd5b50505050825167ffffffffffffffff8111156118ad576118ac614347565b5b6040519080825280602002602001820160405280156118e657816020015b6118d3613767565b8152602001906001900390816118cb5790505b50915060005b83518110156119ba578473ffffffffffffffffffffffffffffffffffffffff16637ece075d858381518110611924576119236154ec565b5b60200260200101516040518263ffffffff1660e01b8152600401611948919061552a565b606060405180830381865afa158015611965573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198991906155a9565b83828151811061199c5761199b6154ec565b5b602002602001018190525080806119b290615605565b9150506118ec565b505092915050565b60608083838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401611a0091906154a4565b600060405180830381600087803b158015611a1a57600080fd5b505af1158015611a2e573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac3919061568b565b905060008173ffffffffffffffffffffffffffffffffffffffff166305d85eda886040518263ffffffff1660e01b8152600401611b0091906156d9565b602060405180830381865afa158015611b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4191906156f4565b90508067ffffffffffffffff811115611b5d57611b5c614347565b5b604051908082528060200260200182016040528015611b8b5781602001602082028036833780820191505090505b5095508067ffffffffffffffff811115611ba857611ba7614347565b5b604051908082528060200260200182016040528015611bd65781602001602082028036833780820191505090505b50945060005b81811015611d675760008373ffffffffffffffffffffffffffffffffffffffff16632c3e50e58a846040518363ffffffff1660e01b8152600401611c21929190615721565b60c060405180830381865afa158015611c3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c629190615802565b90508060800151888381518110611c7c57611c7b6154ec565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff166366f8162e8a8c856040518463ffffffff1660e01b8152600401611cf39392919061582f565b602060405180830381865afa158015611d10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d349190615312565b878381518110611d4757611d466154ec565b5b602002602001018181525050508080611d5f90615605565b915050611bdc565b50505050509250929050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401611db091906154a4565b600060405180830381600087803b158015611dca57600080fd5b505af1158015611dde573d6000803e3d6000fd5b50505050611dea61287e565b73ffffffffffffffffffffffffffffffffffffffff166382df39de86866040518363ffffffff1660e01b8152600401611e24929190615866565b602060405180830381865afa158015611e41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6591906158bb565b9250505092915050565b600083838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401611eac91906154a4565b600060405180830381600087803b158015611ec657600080fd5b505af1158015611eda573d6000803e3d6000fd5b505050506000611f07611ef8611eef886133a5565b6040015161349c565b8661332290919063ffffffff16565b9050611f8a8673ffffffffffffffffffffffffffffffffffffffff16636c376cc56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7b9190615312565b8261332290919063ffffffff16565b93505050509392505050565b611f9e613767565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611fe757600080fd5b505af1158015611ffb573d6000803e3d6000fd5b50505050612008836133a5565b915050919050565b6060815167ffffffffffffffff81111561202d5761202c614347565b5b60405190808252806020026020018201604052801561206657816020015b61205361362f565b81526020019060019003908161204b5790505b50905060005b82518110156120ca576120998484838151811061208c5761208b6154ec565b5b6020026020010151610f81565b8282815181106120ac576120ab6154ec565b5b602002602001018190525080806120c290615605565b91505061206c565b5092915050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161210e91906154a4565b600060405180830381600087803b15801561212857600080fd5b505af115801561213c573d6000803e3d6000fd5b5050505061214861287e565b73ffffffffffffffffffffffffffffffffffffffff1663faaebd21866040518263ffffffff1660e01b815260040161218091906154a4565b602060405180830381865afa15801561219d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c19190615312565b9250505092915050565b60608282905067ffffffffffffffff8111156121ea576121e9614347565b5b60405190808252806020026020018201604052801561222357816020015b6122106136cb565b8152602001906001900390816122085790505b50905060005b838390508110156122955761226484848381811061224a576122496154ec565b5b905060200201602081019061225f9190613899565b611246565b828281518110612277576122766154ec565b5b6020026020010181905250808061228d90615605565b915050612229565b5092915050565b6122a4613573565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016122df91906154a4565b600060405180830381600087803b1580156122f957600080fd5b505af115801561230d573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff16631e0c6fb9866040518263ffffffff1660e01b815260040161234a91906154a4565b60a060405180830381865afa158015612367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238b9190615173565b9250505092915050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156123e057600080fd5b505af11580156123f4573d6000803e3d6000fd5b5050505061240061287e565b73ffffffffffffffffffffffffffffffffffffffff1663a5fdc5de846040518263ffffffff1660e01b815260040161243891906156d9565b602060405180830381865afa158015612455573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124799190615312565b915050919050565b60608173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156124ce573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906124f79190615047565b9050919050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561254957600080fd5b505af115801561255d573d6000803e3d6000fd5b5050505061256961287e565b73ffffffffffffffffffffffffffffffffffffffff1663b4d6f781846040518263ffffffff1660e01b81526004016125a191906156d9565b602060405180830381865afa1580156125be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e29190615312565b915050919050565b6125f26135a0565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561263b57600080fd5b505af115801561264f573d6000803e3d6000fd5b5050505061265c836131d5565b915050919050565b61266c6135a0565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016126a791906154a4565b600060405180830381600087803b1580156126c157600080fd5b505af11580156126d5573d6000803e3d6000fd5b505050506127786126f16126e8866133a5565b6040015161349c565b8573ffffffffffffffffffffffffffffffffffffffff1663b7648fb9886040518263ffffffff1660e01b815260040161272a91906154a4565b6040805180830381865afa158015612746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276a91906154bf565b6134ae90919063ffffffff16565b9250505092915050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016127bf91906154a4565b600060405180830381600087803b1580156127d957600080fd5b505af11580156127ed573d6000803e3d6000fd5b505050506127f961287e565b73ffffffffffffffffffffffffffffffffffffffff1663cc218ece86866040518363ffffffff1660e01b8152600401612833929190615866565b602060405180830381865afa158015612850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128749190615312565b9250505092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d8dfeb456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290f9190615926565b905090565b61291c6135a0565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161295791906154a4565b600060405180830381600087803b15801561297157600080fd5b505af1158015612985573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663b7648fb9866040518263ffffffff1660e01b81526004016129c291906154a4565b6040805180830381865afa1580156129de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0291906154bf565b9250505092915050565b612a146135a0565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a5d57600080fd5b505af1158015612a71573d6000803e3d6000fd5b50505050612aa4612a8d612a84856133a5565b6040015161349c565b612a96856131d5565b6134ae90919063ffffffff16565b915050919050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401612ae991906154a4565b600060405180830381600087803b158015612b0357600080fd5b505af1158015612b17573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff166358ca6f98866040518263ffffffff1660e01b8152600401612b5491906154a4565b602060405180830381865afa158015612b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b9591906158bb565b9250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60608085858073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401612c0191906154a4565b600060405180830381600087803b158015612c1b57600080fd5b505af1158015612c2f573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc4919061568b565b90508686905067ffffffffffffffff811115612ce357612ce2614347565b5b604051908082528060200260200182016040528015612d115781602001602082028036833780820191505090505b5094508686905067ffffffffffffffff811115612d3157612d30614347565b5b604051908082528060200260200182016040528015612d5f5781602001602082028036833780820191505090505b50935060005b87879050811015612f255760008273ffffffffffffffffffffffffffffffffffffffff16632c3e50e58b8b8b86818110612da257612da16154ec565b5b905060200201356040518363ffffffff1660e01b8152600401612dc6929190615721565b60c060405180830381865afa158015612de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e079190615802565b90508060800151878381518110612e2157612e206154ec565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff166366f8162e8b8d8c8c87818110612e8c57612e8b6154ec565b5b905060200201356040518463ffffffff1660e01b8152600401612eb19392919061582f565b602060405180830381865afa158015612ece573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef29190615312565b868381518110612f0557612f046154ec565b5b602002602001018181525050508080612f1d90615605565b915050612d65565b5050505094509492505050565b600080828073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612f7e57600080fd5b505af1158015612f92573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613003573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130279190615968565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632d809cb6876040518263ffffffff1660e01b815260040161308491906156d9565b602060405180830381865afa1580156130a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c59190615968565b90506130cf61287e565b73ffffffffffffffffffffffffffffffffffffffff1663faaebd21836040518263ffffffff1660e01b815260040161310791906154a4565b602060405180830381865afa158015613124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131489190615312565b945061315261287e565b73ffffffffffffffffffffffffffffffffffffffff1663faaebd21826040518263ffffffff1660e01b815260040161318a91906154a4565b602060405180830381865afa1580156131a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131cb9190615312565b9350505050915091565b6131dd6135a0565b8173ffffffffffffffffffffffffffffffffffffffff16639a427d038373ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613244573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326891906156f4565b6040518263ffffffff1660e01b8152600401613284919061552a565b6040805180830381865afa1580156132a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c491906154bf565b9050919050565b600060026132d984846134ff565b14905092915050565b600060016132f084846134ff565b14905092915050565b600081670de0b6b3a7640000846133109190615995565b61331a9190615a1e565b905092915050565b6000670de0b6b3a764000082846133399190615995565b6133439190615a1e565b905092915050565b6000613357838361353d565b905092915050565b6000670de0b6b3a7640000826133759190615a4f565b9050919050565b6000670de0b6b3a764000082846133939190615a4f565b61339d9190615b66565b905092915050565b6133ad613767565b8173ffffffffffffffffffffffffffffffffffffffff16637ece075d8373ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613414573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343891906156f4565b6040518263ffffffff1660e01b8152600401613454919061552a565b606060405180830381865afa158015613471573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349591906155a9565b9050919050565b60006134a782613557565b9050919050565b6134b66135a0565b60405180604001604052806134d884866000015161332290919063ffffffff16565b81526020016134f484866020015161332290919063ffffffff16565b815250905092915050565b60008060008484915091508082111561351d57600292505050613537565b8082101561353057600092505050613537565b6001925050505b92915050565b60008183101561354d578161354f565b825b905092915050565b60008082121561356a578160000361356c565b815b9050919050565b60405180606001604052806000815260200161358d6135a0565b815260200161359a6135a0565b81525090565b604051806040016040528060008152602001600081525090565b60405180610140016040528060608152602001606081526020016135dc613788565b8152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016136296137d2565b81525090565b604051806101600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200161368b613573565b81526020016136986135a0565b81526020016000151581526020016000151581526020016136b76135a0565b815260200160008152602001600081525090565b604051806101a001604052806136df6135ba565b8152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001613717613767565b8152602001600081526020016000815260200160008152602001613739613573565b81526020016137466135a0565b815260200160008152602001600081526020016137616135a0565b81525090565b60405180606001604052806000815260200160008152602001600081525090565b6040518060600160405280600060018111156137a7576137a6613ae8565b5b8152602001600060018111156137c0576137bf613ae8565b5b8152602001600061ffff191681525090565b60405180608001604052806000600f0b81526020016000600f0b81526020016000600f0b815260200160006fffffffffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061385482613829565b9050919050565b600061386682613849565b9050919050565b6138768161385b565b811461388157600080fd5b50565b6000813590506138938161386d565b92915050565b6000602082840312156138af576138ae61381f565b5b60006138bd84828501613884565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156139005780820151818401526020810190506138e5565b8381111561390f576000848401525b50505050565b6000601f19601f8301169050919050565b6000613931826138c6565b61393b81856138d1565b935061394b8185602086016138e2565b61395481613915565b840191505092915050565b600060208201905081810360008301526139798184613926565b905092915050565b6000819050919050565b61399481613981565b82525050565b6000819050919050565b60006139bf6139ba6139b584613981565b61399a565b613981565b9050919050565b6139cf816139a4565b82525050565b6040820160008201516139eb60008501826139c6565b5060208201516139fe60208501826139c6565b50505050565b60a082016000820151613a1a600085018261398b565b506020820151613a2d60208501826139d5565b506040820151613a4060608501826139d5565b50505050565b604082016000820151613a5c60008501826139c6565b506020820151613a6f60208501826139c6565b50505050565b600060e082019050613a8a6000830185613a04565b613a9760a0830184613a46565b9392505050565b600082825260208201905092915050565b6000613aba826138c6565b613ac48185613a9e565b9350613ad48185602086016138e2565b613add81613915565b840191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613b2857613b27613ae8565b5b50565b6000819050613b3982613b17565b919050565b6000613b4982613b2b565b9050919050565b613b5981613b3e565b82525050565b60028110613b7057613b6f613ae8565b5b50565b6000819050613b8182613b5f565b919050565b6000613b9182613b73565b9050919050565b613ba181613b86565b82525050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000082169050919050565b613bdc81613ba7565b82525050565b606082016000820151613bf86000850182613b50565b506020820151613c0b6020850182613b98565b506040820151613c1e6040850182613bd3565b50505050565b6000613c3f613c3a613c3584613829565b61399a565b613829565b9050919050565b6000613c5182613c24565b9050919050565b6000613c6382613c46565b9050919050565b613c7381613c58565b82525050565b600081600f0b9050919050565b6000613ca1613c9c613c9784613c79565b61399a565b613c79565b9050919050565b613cb181613c86565b82525050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6000613cee613ce9613ce484613cb7565b61399a565b613cb7565b9050919050565b613cfe81613cd3565b82525050565b608082016000820151613d1a6000850182613ca8565b506020820151613d2d6020850182613ca8565b506040820151613d406040850182613ca8565b506060820151613d536060850182613cf5565b50505050565b60006101e0830160008301518482036000860152613d778282613aaf565b91505060208301518482036020860152613d918282613aaf565b9150506040830151613da66040860182613be2565b506060830151613db960a0860182613c6a565b506080830151613dcc60c08601826139c6565b5060a0830151613ddf60e08601826139c6565b5060c0830151613df36101008601826139c6565b5060e0830151613e076101208601826139c6565b50610100830151613e1c6101408601826139c6565b50610120830151613e31610160860182613d04565b508091505092915050565b60006020820190508181036000830152613e568184613d59565b905092915050565b6000819050919050565b6000613e83613e7e613e7984613e5e565b61399a565b613e5e565b9050919050565b613e9381613e68565b82525050565b6000602082019050613eae6000830184613e8a565b92915050565b600060a082019050613ec96000830184613a04565b92915050565b613ed881613849565b8114613ee357600080fd5b50565b600081359050613ef581613ecf565b92915050565b60008060408385031215613f1257613f1161381f565b5b6000613f2085828601613ee6565b9250506020613f3185828601613884565b9150509250929050565b613f4481613849565b82525050565b60a082016000820151613f60600085018261398b565b506020820151613f7360208501826139d5565b506040820151613f8660608501826139d5565b50505050565b60008115159050919050565b613fa181613f8c565b82525050565b61022082016000820151613fbe6000850182613f3b565b506020820151613fd16020850182613f3b565b506040820151613fe460408501826139c6565b506060820151613ff760608501826139c6565b50608082015161400a6080850182613f4a565b5060a082015161401e6101208501826139d5565b5060c0820151614032610160850182613f98565b5060e0820151614046610180850182613f98565b5061010082015161405b6101a08501826139d5565b506101208201516140706101e08501826139c6565b506101408201516140856102008501826139c6565b50505050565b6000610220820190506140a16000830184613fa7565b92915050565b6140b0816139a4565b82525050565b60006020820190506140cb60008301846140a7565b92915050565b60006101e08301600083015184820360008601526140ef8282613aaf565b915050602083015184820360208601526141098282613aaf565b915050604083015161411e6040860182613be2565b50606083015161413160a0860182613c6a565b50608083015161414460c08601826139c6565b5060a083015161415760e08601826139c6565b5060c083015161416b6101008601826139c6565b5060e083015161417f6101208601826139c6565b506101008301516141946101408601826139c6565b506101208301516141a9610160860182613d04565b508091505092915050565b6141bd81613e68565b82525050565b6060820160008201516141d9600085018261398b565b5060208201516141ec602085018261398b565b5060408201516141ff60408501826141b4565b50505050565b60006102a083016000830151848203600086015261422382826140d1565b91505060208301516142386020860182613f3b565b50604083015161424b60408601826141b4565b50606083015161425e60608601826141b4565b50608083015161427160808601826141c3565b5060a083015161428460e08601826139c6565b5060c08301516142986101008601826139c6565b5060e08301516142ac6101208601826139c6565b506101008301516142c1610140860182613f4a565b506101208301516142d66101e08601826139d5565b506101408301516142eb6102208601826139c6565b506101608301516143006102408601826139c6565b506101808301516143156102608601826139d5565b508091505092915050565b6000602082019050818103600083015261433a8184614205565b905092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61437f82613915565b810181811067ffffffffffffffff8211171561439e5761439d614347565b5b80604052505050565b60006143b1613815565b90506143bd8282614376565b919050565b600067ffffffffffffffff8211156143dd576143dc614347565b5b602082029050602081019050919050565b600080fd5b6143fc81613981565b811461440757600080fd5b50565b600081359050614419816143f3565b92915050565b600061443261442d846143c2565b6143a7565b90508083825260208201905060208402830185811115614455576144546143ee565b5b835b8181101561447e578061446a888261440a565b845260208401935050602081019050614457565b5050509392505050565b600082601f83011261449d5761449c614342565b5b81356144ad84826020860161441f565b91505092915050565b600080604083850312156144cd576144cc61381f565b5b60006144db85828601613884565b925050602083013567ffffffffffffffff8111156144fc576144fb613824565b5b61450885828601614488565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061454a83836141c3565b60608301905092915050565b6000602082019050919050565b600061456e82614512565b614578818561451d565b93506145838361452e565b8060005b838110156145b457815161459b888261453e565b97506145a683614556565b925050600181019050614587565b5085935050505092915050565b600060208201905081810360008301526145db8184614563565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061461a82613c46565b9050919050565b61462a8161460f565b82525050565b600061463c8383614621565b60208301905092915050565b6000602082019050919050565b6000614660826145e3565b61466a81856145ee565b9350614675836145ff565b8060005b838110156146a657815161468d8882614630565b975061469883614648565b925050600181019050614679565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006146eb83836139c6565b60208301905092915050565b6000602082019050919050565b600061470f826146b3565b61471981856146be565b9350614724836146cf565b8060005b8381101561475557815161473c88826146df565b9750614747836146f7565b925050600181019050614728565b5085935050505092915050565b6000604082019050818103600083015261477c8185614655565b905081810360208301526147908184614704565b90509392505050565b6147a281613f8c565b82525050565b60006020820190506147bd6000830184614799565b92915050565b6147cc81613981565b81146147d757600080fd5b50565b6000813590506147e9816147c3565b92915050565b6000806000606084860312156148085761480761381f565b5b600061481686828701613ee6565b935050602061482786828701613884565b9250506040614838868287016147da565b9150509250925092565b606082016000820151614858600085018261398b565b50602082015161486b602085018261398b565b50604082015161487e60408501826141b4565b50505050565b60006060820190506148996000830184614842565b92915050565b600067ffffffffffffffff8211156148ba576148b9614347565b5b602082029050602081019050919050565b60006148de6148d98461489f565b6143a7565b90508083825260208201905060208402830185811115614901576149006143ee565b5b835b8181101561492a57806149168882613884565b845260208401935050602081019050614903565b5050509392505050565b600082601f83011261494957614948614342565b5b81356149598482602086016148cb565b91505092915050565b600080604083850312156149795761497861381f565b5b600061498785828601613ee6565b925050602083013567ffffffffffffffff8111156149a8576149a7613824565b5b6149b485828601614934565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61022082016000820151614a016000850182613f3b565b506020820151614a146020850182613f3b565b506040820151614a2760408501826139c6565b506060820151614a3a60608501826139c6565b506080820151614a4d6080850182613f4a565b5060a0820151614a616101208501826139d5565b5060c0820151614a75610160850182613f98565b5060e0820151614a89610180850182613f98565b50610100820151614a9e6101a08501826139d5565b50610120820151614ab36101e08501826139c6565b50610140820151614ac86102008501826139c6565b50505050565b6000614ada83836149ea565b6102208301905092915050565b6000602082019050919050565b6000614aff826149be565b614b0981856149c9565b9350614b14836149da565b8060005b83811015614b45578151614b2c8882614ace565b9750614b3783614ae7565b925050600181019050614b18565b5085935050505092915050565b60006020820190508181036000830152614b6c8184614af4565b905092915050565b600080fd5b60008083601f840112614b8f57614b8e614342565b5b8235905067ffffffffffffffff811115614bac57614bab614b74565b5b602083019150836020820283011115614bc857614bc76143ee565b5b9250929050565b60008060208385031215614be657614be561381f565b5b600083013567ffffffffffffffff811115614c0457614c03613824565b5b614c1085828601614b79565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006102a0830160008301518482036000860152614c6682826140d1565b9150506020830151614c7b6020860182613f3b565b506040830151614c8e60408601826141b4565b506060830151614ca160608601826141b4565b506080830151614cb460808601826141c3565b5060a0830151614cc760e08601826139c6565b5060c0830151614cdb6101008601826139c6565b5060e0830151614cef6101208601826139c6565b50610100830151614d04610140860182613f4a565b50610120830151614d196101e08601826139d5565b50610140830151614d2e6102208601826139c6565b50610160830151614d436102408601826139c6565b50610180830151614d586102608601826139d5565b508091505092915050565b6000614d6f8383614c48565b905092915050565b6000602082019050919050565b6000614d8f82614c1c565b614d998185614c27565b935083602082028501614dab85614c38565b8060005b85811015614de75784840389528151614dc88582614d63565b9450614dd383614d77565b925060208a01995050600181019050614daf565b50829750879550505050505092915050565b60006020820190508181036000830152614e138184614d84565b905092915050565b6000604082019050614e306000830184613a46565b92915050565b6000614e4182613c46565b9050919050565b614e5181614e36565b82525050565b6000602082019050614e6c6000830184614e48565b92915050565b6000614e7d82613c46565b9050919050565b614e8d81614e72565b82525050565b6000602082019050614ea86000830184614e84565b92915050565b60008083601f840112614ec457614ec3614342565b5b8235905067ffffffffffffffff811115614ee157614ee0614b74565b5b602083019150836020820283011115614efd57614efc6143ee565b5b9250929050565b60008060008060608587031215614f1e57614f1d61381f565b5b6000614f2c87828801613ee6565b9450506020614f3d87828801613884565b935050604085013567ffffffffffffffff811115614f5e57614f5d613824565b5b614f6a87828801614eae565b925092505092959194509250565b6000604082019050614f8d60008301856140a7565b614f9a60208301846140a7565b9392505050565b600080fd5b600067ffffffffffffffff821115614fc157614fc0614347565b5b614fca82613915565b9050602081019050919050565b6000614fea614fe584614fa6565b6143a7565b90508281526020810184848401111561500657615005614fa1565b5b6150118482856138e2565b509392505050565b600082601f83011261502e5761502d614342565b5b815161503e848260208601614fd7565b91505092915050565b60006020828403121561505d5761505c61381f565b5b600082015167ffffffffffffffff81111561507b5761507a613824565b5b61508784828501615019565b91505092915050565b600080fd5b6000815190506150a4816143f3565b92915050565b6000815190506150b9816147c3565b92915050565b6000604082840312156150d5576150d4615090565b5b6150df60406143a7565b905060006150ef848285016150aa565b6000830152506020615103848285016150aa565b60208301525092915050565b600060a0828403121561512557615124615090565b5b61512f60606143a7565b9050600061513f84828501615095565b6000830152506020615153848285016150bf565b6020830152506060615167848285016150bf565b60408301525092915050565b600060a082840312156151895761518861381f565b5b60006151978482850161510f565b91505092915050565b600281106151ad57600080fd5b50565b6000815190506151bf816151a0565b92915050565b600281106151d257600080fd5b50565b6000815190506151e4816151c5565b92915050565b6151f381613ba7565b81146151fe57600080fd5b50565b600081519050615210816151ea565b92915050565b60006060828403121561522c5761522b615090565b5b61523660606143a7565b90506000615246848285016151b0565b600083015250602061525a848285016151d5565b602083015250604061526e84828501615201565b60408301525092915050565b6000606082840312156152905761528f61381f565b5b600061529e84828501615216565b91505092915050565b60006152b282613849565b9050919050565b6152c2816152a7565b81146152cd57600080fd5b50565b6000815190506152df816152b9565b92915050565b6000602082840312156152fb576152fa61381f565b5b6000615309848285016152d0565b91505092915050565b6000602082840312156153285761532761381f565b5b6000615336848285016150aa565b91505092915050565b61534881613c79565b811461535357600080fd5b50565b6000815190506153658161533f565b92915050565b61537481613cb7565b811461537f57600080fd5b50565b6000815190506153918161536b565b92915050565b6000608082840312156153ad576153ac615090565b5b6153b760806143a7565b905060006153c784828501615356565b60008301525060206153db84828501615356565b60208301525060406153ef84828501615356565b604083015250606061540384828501615382565b60608301525092915050565b6000608082840312156154255761542461381f565b5b600061543384828501615397565b91505092915050565b61544581613e5e565b811461545057600080fd5b50565b6000815190506154628161543c565b92915050565b60006020828403121561547e5761547d61381f565b5b600061548c84828501615453565b91505092915050565b61549e81613849565b82525050565b60006020820190506154b96000830184615495565b92915050565b6000604082840312156154d5576154d461381f565b5b60006154e3848285016150bf565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61552481613981565b82525050565b600060208201905061553f600083018461551b565b92915050565b60006060828403121561555b5761555a615090565b5b61556560606143a7565b9050600061557584828501615095565b600083015250602061558984828501615095565b602083015250604061559d84828501615453565b60408301525092915050565b6000606082840312156155bf576155be61381f565b5b60006155cd84828501615545565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061561082613981565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615642576156416155d6565b5b600182019050919050565b600061565882613849565b9050919050565b6156688161564d565b811461567357600080fd5b50565b6000815190506156858161565f565b92915050565b6000602082840312156156a1576156a061381f565b5b60006156af84828501615676565b91505092915050565b60006156c382613c46565b9050919050565b6156d3816156b8565b82525050565b60006020820190506156ee60008301846156ca565b92915050565b60006020828403121561570a5761570961381f565b5b600061571884828501615095565b91505092915050565b600060408201905061573660008301856156ca565b615743602083018461551b565b9392505050565b61575381613849565b811461575e57600080fd5b50565b6000815190506157708161574a565b92915050565b600060c0828403121561578c5761578b615090565b5b61579660a06143a7565b905060006157a684828501615095565b60008301525060206157ba848285016150bf565b60208301525060606157ce84828501615095565b60408301525060806157e284828501615095565b60608301525060a06157f684828501615761565b60808301525092915050565b600060c082840312156158185761581761381f565b5b600061582684828501615776565b91505092915050565b600060608201905061584460008301866156ca565b6158516020830185615495565b61585e604083018461551b565b949350505050565b600060408201905061587b6000830185615495565b61588860208301846156ca565b9392505050565b61589881613f8c565b81146158a357600080fd5b50565b6000815190506158b58161588f565b92915050565b6000602082840312156158d1576158d061381f565b5b60006158df848285016158a6565b91505092915050565b60006158f382613849565b9050919050565b615903816158e8565b811461590e57600080fd5b50565b600081519050615920816158fa565b92915050565b60006020828403121561593c5761593b61381f565b5b600061594a84828501615911565b91505092915050565b60008151905061596281613ecf565b92915050565b60006020828403121561597e5761597d61381f565b5b600061598c84828501615953565b91505092915050565b60006159a082613981565b91506159ab83613981565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156159e4576159e36155d6565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000615a2982613981565b9150615a3483613981565b925082615a4457615a436159ef565b5b828204905092915050565b6000615a5a82613e5e565b9150615a6583613e5e565b9250827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482116000841360008413161615615aa457615aa36155d6565b5b817f80000000000000000000000000000000000000000000000000000000000000000583126000841260008413161615615ae157615ae06155d6565b5b827f80000000000000000000000000000000000000000000000000000000000000000582126000841360008412161615615b1e57615b1d6155d6565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0582126000841260008412161615615b5b57615b5a6155d6565b5b828202905092915050565b6000615b7182613e5e565b9150615b7c83613e5e565b925082615b8c57615b8b6159ef565b5b600160000383147f800000000000000000000000000000000000000000000000000000000000000083141615615bc557615bc46155d6565b5b82820590509291505056fea2646970667358221220e650dd4b391677aa40c90d4f7f374c06bf08ad9fbde8ed1f78d106103771142064736f6c634300080f0033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061020b5760003560e01c80638f5edc081161012a578063b7a98f97116100bd578063edd8ca7b1161008c578063f77c479111610071578063f77c4791146107a1578063f8083f56146107bf578063faaebd21146107f05761020b565b8063edd8ca7b14610741578063f5c06e1b146107715761020b565b8063b7a98f9714610693578063cc218ece146106c3578063d8dfeb45146106f3578063e9c6b4c1146107115761020b565b8063a5fdc5de116100f9578063a5fdc5de146105d3578063a86e357614610603578063b4d6f78114610633578063b7648fb9146106635761020b565b80638f5edc08146105135780639b9ac2cb146105435780639bc02857146105735780639be2a567146105a35761020b565b806337e710ac116101a25780637e64cc13116101715780637e64cc131461045257806382df39de146104835780638e076924146104b35780638e480b20146104e35761020b565b806337e710ac14610391578063540027e6146103c15780636878353e146103f15780636efef085146104225761020b565b80631e0c6fb9116101de5780631e0c6fb9146102d1578063204e94b014610301578063237e58991461033157806326512160146103615761020b565b80630198489214610210578063036790c0146102405780630aae7a6b146102715780630ba9d8ca146102a1575b600080fd5b61022a60048036038101906102259190613899565b610821565b604051610237919061395f565b60405180910390f35b61025a60048036038101906102559190613899565b61089e565b604051610268929190613a75565b60405180910390f35b61028b60048036038101906102869190613899565b610991565b6040516102989190613e3c565b60405180910390f35b6102bb60048036038101906102b69190613899565b610dae565b6040516102c89190613e99565b60405180910390f35b6102eb60048036038101906102e69190613899565b610ea1565b6040516102f89190613eb4565b60405180910390f35b61031b60048036038101906103169190613efb565b610f81565b604051610328919061408b565b60405180910390f35b61034b60048036038101906103469190613efb565b611125565b60405161035891906140b6565b60405180910390f35b61037b60048036038101906103769190613899565b611246565b6040516103889190614320565b60405180910390f35b6103ab60048036038101906103a69190613efb565b61142d565b6040516103b891906140b6565b60405180910390f35b6103db60048036038101906103d69190613899565b6115a2565b6040516103e89190613e99565b60405180910390f35b61040b60048036038101906104069190613efb565b6116b2565b604051610419929190613a75565b60405180910390f35b61043c600480360381019061043791906144b6565b61182f565b60405161044991906145c1565b60405180910390f35b61046c60048036038101906104679190613efb565b6119c2565b60405161047a929190614762565b60405180910390f35b61049d60048036038101906104989190613efb565b611d73565b6040516104aa91906147a8565b60405180910390f35b6104cd60048036038101906104c891906147ef565b611e6f565b6040516104da91906140b6565b60405180910390f35b6104fd60048036038101906104f89190613899565b611f96565b60405161050a9190614884565b60405180910390f35b61052d60048036038101906105289190614962565b612010565b60405161053a9190614b52565b60405180910390f35b61055d60048036038101906105589190613efb565b6120d1565b60405161056a91906140b6565b60405180910390f35b61058d60048036038101906105889190614bcf565b6121cb565b60405161059a9190614df9565b60405180910390f35b6105bd60048036038101906105b89190613efb565b61229c565b6040516105ca9190613eb4565b60405180910390f35b6105ed60048036038101906105e89190613899565b612395565b6040516105fa91906140b6565b60405180910390f35b61061d60048036038101906106189190613899565b612481565b60405161062a919061395f565b60405180910390f35b61064d60048036038101906106489190613899565b6124fe565b60405161065a91906140b6565b60405180910390f35b61067d60048036038101906106789190613899565b6125ea565b60405161068a9190614e1b565b60405180910390f35b6106ad60048036038101906106a89190613efb565b612664565b6040516106ba9190614e1b565b60405180910390f35b6106dd60048036038101906106d89190613efb565b612782565b6040516106ea91906140b6565b60405180910390f35b6106fb61287e565b6040516107089190614e57565b60405180910390f35b61072b60048036038101906107269190613efb565b612914565b6040516107389190614e1b565b60405180910390f35b61075b60048036038101906107569190613899565b612a0c565b6040516107689190614e1b565b60405180910390f35b61078b60048036038101906107869190613efb565b612aac565b60405161079891906147a8565b60405180910390f35b6107a9612b9f565b6040516107b69190614e93565b60405180910390f35b6107d960048036038101906107d49190614f04565b612bc3565b6040516107e7929190614762565b60405180910390f35b61080a60048036038101906108059190613899565b612f32565b604051610818929190614f78565b60405180910390f35b60608173ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561086e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906108979190615047565b9050919050565b6108a6613573565b6108ae6135a0565b828073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156108f757600080fd5b505af115801561090b573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff166359ea287d6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561095a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097e9190615173565b610987856131d5565b9250925050915091565b6109996135ba565b6109a282610821565b81600001819052506109b382612481565b81602001819052508173ffffffffffffffffffffffffffffffffffffffff166305d5c1cb6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610a06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2a919061527a565b81604001819052508173ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa191906152e5565b816060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff16636c376cc56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b479190615312565b8160800181815250508173ffffffffffffffffffffffffffffffffffffffff16635d16e1206040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbf9190615312565b8160a00181815250508173ffffffffffffffffffffffffffffffffffffffff1663fc741c7c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c379190615312565b8160c00181815250508173ffffffffffffffffffffffffffffffffffffffff166343f0179b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610caf9190615312565b8160e00181815250508173ffffffffffffffffffffffffffffffffffffffff1663193775676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d279190615312565b816101000181815250508173ffffffffffffffffffffffffffffffffffffffff1663a12e1b336040518163ffffffff1660e01b8152600401608060405180830381865afa158015610d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da0919061540f565b816101200181905250919050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610df957600080fd5b505af1158015610e0d573d6000803e3d6000fd5b505050506000610e1c846131d5565b90508373ffffffffffffffffffffffffffffffffffffffff166360ec91d6826040518263ffffffff1660e01b8152600401610e579190614e1b565b602060405180830381865afa158015610e74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e989190615468565b92505050919050565b610ea9613573565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ef257600080fd5b505af1158015610f06573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166359ea287d6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610f55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f799190615173565b915050919050565b610f8961362f565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401610fc491906154a4565b600060405180830381600087803b158015610fde57600080fd5b505af1158015610ff2573d6000803e3d6000fd5b5050505083836000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084836020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506110708585612782565b836040018181525050611083858561142d565b836060018181525050611096858561229c565b83608001819052506110a88585612914565b8360a001819052506110ba8585611d73565b8360c00190151590811515815250506110d38585612aac565b8360e00190151590811515815250506110ec8585612664565b8361010001819052506110ff85856120d1565b836101200181815250506111138585611125565b83610140018181525050505092915050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161116291906154a4565b600060405180830381600087803b15801561117c57600080fd5b505af1158015611190573d6000803e3d6000fd5b5050505060006111a08686612664565b90506111ba600082602001516132cb90919063ffffffff16565b156111cc57806020015193505061123e565b60006111d78661089e565b9150506111f2600082600001516132e290919063ffffffff16565b156112025760009450505061123e565b600061121f826000015183602001516132f990919063ffffffff16565b905061123883600001518261332290919063ffffffff16565b95505050505b505092915050565b61124e6136cb565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561129757600080fd5b505af11580156112ab573d6000803e3d6000fd5b505050506112b883610991565b826000018190525082826020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505061130183610dae565b826040018181525050611313836115a2565b82606001818152505061132583611f96565b82608001819052508273ffffffffffffffffffffffffffffffffffffffff16636c376cc56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c9190615312565b8260a00181815250506113ae83612395565b8260c00181815250506113c0836124fe565b8260e00181815250506113d283610ea1565b8261010001819052506113e4836125ea565b8261012001819052506000806113f985612f32565b915091508184610140018181525050808461016001818152505061141c85612a0c565b846101800181905250505050919050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161146a91906154a4565b600060405180830381600087803b15801561148457600080fd5b505af1158015611498573d6000803e3d6000fd5b505050506115988473ffffffffffffffffffffffffffffffffffffffff166391689024876040518263ffffffff1660e01b81526004016114d891906154a4565b602060405180830381865afa1580156114f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115199190615312565b8573ffffffffffffffffffffffffffffffffffffffff1663ab582f29886040518263ffffffff1660e01b815260040161155291906154a4565b602060405180830381865afa15801561156f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115939190615312565b61334b565b9250505092915050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156115ed57600080fd5b505af1158015611601573d6000803e3d6000fd5b505050506000611610846131d5565b90506116a96116216201518061335f565b8573ffffffffffffffffffffffffffffffffffffffff166360ec91d6846040518263ffffffff1660e01b815260040161165a9190614e1b565b602060405180830381865afa158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b9190615468565b61337c90919063ffffffff16565b92505050919050565b6116ba613573565b6116c26135a0565b83838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016116fd91906154a4565b600060405180830381600087803b15801561171757600080fd5b505af115801561172b573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff16631e0c6fb9876040518263ffffffff1660e01b815260040161176891906154a4565b60a060405180830381865afa158015611785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a99190615173565b8573ffffffffffffffffffffffffffffffffffffffff1663b7648fb9886040518263ffffffff1660e01b81526004016117e291906154a4565b6040805180830381865afa1580156117fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182291906154bf565b9350935050509250929050565b6060828073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561187a57600080fd5b505af115801561188e573d6000803e3d6000fd5b50505050825167ffffffffffffffff8111156118ad576118ac614347565b5b6040519080825280602002602001820160405280156118e657816020015b6118d3613767565b8152602001906001900390816118cb5790505b50915060005b83518110156119ba578473ffffffffffffffffffffffffffffffffffffffff16637ece075d858381518110611924576119236154ec565b5b60200260200101516040518263ffffffff1660e01b8152600401611948919061552a565b606060405180830381865afa158015611965573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198991906155a9565b83828151811061199c5761199b6154ec565b5b602002602001018190525080806119b290615605565b9150506118ec565b505092915050565b60608083838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401611a0091906154a4565b600060405180830381600087803b158015611a1a57600080fd5b505af1158015611a2e573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac3919061568b565b905060008173ffffffffffffffffffffffffffffffffffffffff166305d85eda886040518263ffffffff1660e01b8152600401611b0091906156d9565b602060405180830381865afa158015611b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4191906156f4565b90508067ffffffffffffffff811115611b5d57611b5c614347565b5b604051908082528060200260200182016040528015611b8b5781602001602082028036833780820191505090505b5095508067ffffffffffffffff811115611ba857611ba7614347565b5b604051908082528060200260200182016040528015611bd65781602001602082028036833780820191505090505b50945060005b81811015611d675760008373ffffffffffffffffffffffffffffffffffffffff16632c3e50e58a846040518363ffffffff1660e01b8152600401611c21929190615721565b60c060405180830381865afa158015611c3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c629190615802565b90508060800151888381518110611c7c57611c7b6154ec565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff166366f8162e8a8c856040518463ffffffff1660e01b8152600401611cf39392919061582f565b602060405180830381865afa158015611d10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d349190615312565b878381518110611d4757611d466154ec565b5b602002602001018181525050508080611d5f90615605565b915050611bdc565b50505050509250929050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401611db091906154a4565b600060405180830381600087803b158015611dca57600080fd5b505af1158015611dde573d6000803e3d6000fd5b50505050611dea61287e565b73ffffffffffffffffffffffffffffffffffffffff166382df39de86866040518363ffffffff1660e01b8152600401611e24929190615866565b602060405180830381865afa158015611e41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6591906158bb565b9250505092915050565b600083838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401611eac91906154a4565b600060405180830381600087803b158015611ec657600080fd5b505af1158015611eda573d6000803e3d6000fd5b505050506000611f07611ef8611eef886133a5565b6040015161349c565b8661332290919063ffffffff16565b9050611f8a8673ffffffffffffffffffffffffffffffffffffffff16636c376cc56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7b9190615312565b8261332290919063ffffffff16565b93505050509392505050565b611f9e613767565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611fe757600080fd5b505af1158015611ffb573d6000803e3d6000fd5b50505050612008836133a5565b915050919050565b6060815167ffffffffffffffff81111561202d5761202c614347565b5b60405190808252806020026020018201604052801561206657816020015b61205361362f565b81526020019060019003908161204b5790505b50905060005b82518110156120ca576120998484838151811061208c5761208b6154ec565b5b6020026020010151610f81565b8282815181106120ac576120ab6154ec565b5b602002602001018190525080806120c290615605565b91505061206c565b5092915050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161210e91906154a4565b600060405180830381600087803b15801561212857600080fd5b505af115801561213c573d6000803e3d6000fd5b5050505061214861287e565b73ffffffffffffffffffffffffffffffffffffffff1663faaebd21866040518263ffffffff1660e01b815260040161218091906154a4565b602060405180830381865afa15801561219d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c19190615312565b9250505092915050565b60608282905067ffffffffffffffff8111156121ea576121e9614347565b5b60405190808252806020026020018201604052801561222357816020015b6122106136cb565b8152602001906001900390816122085790505b50905060005b838390508110156122955761226484848381811061224a576122496154ec565b5b905060200201602081019061225f9190613899565b611246565b828281518110612277576122766154ec565b5b6020026020010181905250808061228d90615605565b915050612229565b5092915050565b6122a4613573565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016122df91906154a4565b600060405180830381600087803b1580156122f957600080fd5b505af115801561230d573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff16631e0c6fb9866040518263ffffffff1660e01b815260040161234a91906154a4565b60a060405180830381865afa158015612367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238b9190615173565b9250505092915050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156123e057600080fd5b505af11580156123f4573d6000803e3d6000fd5b5050505061240061287e565b73ffffffffffffffffffffffffffffffffffffffff1663a5fdc5de846040518263ffffffff1660e01b815260040161243891906156d9565b602060405180830381865afa158015612455573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124799190615312565b915050919050565b60608173ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156124ce573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906124f79190615047565b9050919050565b6000818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561254957600080fd5b505af115801561255d573d6000803e3d6000fd5b5050505061256961287e565b73ffffffffffffffffffffffffffffffffffffffff1663b4d6f781846040518263ffffffff1660e01b81526004016125a191906156d9565b602060405180830381865afa1580156125be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e29190615312565b915050919050565b6125f26135a0565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561263b57600080fd5b505af115801561264f573d6000803e3d6000fd5b5050505061265c836131d5565b915050919050565b61266c6135a0565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016126a791906154a4565b600060405180830381600087803b1580156126c157600080fd5b505af11580156126d5573d6000803e3d6000fd5b505050506127786126f16126e8866133a5565b6040015161349c565b8573ffffffffffffffffffffffffffffffffffffffff1663b7648fb9886040518263ffffffff1660e01b815260040161272a91906154a4565b6040805180830381865afa158015612746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061276a91906154bf565b6134ae90919063ffffffff16565b9250505092915050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b81526004016127bf91906154a4565b600060405180830381600087803b1580156127d957600080fd5b505af11580156127ed573d6000803e3d6000fd5b505050506127f961287e565b73ffffffffffffffffffffffffffffffffffffffff1663cc218ece86866040518363ffffffff1660e01b8152600401612833929190615866565b602060405180830381865afa158015612850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128749190615312565b9250505092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d8dfeb456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290f9190615926565b905090565b61291c6135a0565b82828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161295791906154a4565b600060405180830381600087803b15801561297157600080fd5b505af1158015612985573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663b7648fb9866040518263ffffffff1660e01b81526004016129c291906154a4565b6040805180830381865afa1580156129de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0291906154bf565b9250505092915050565b612a146135a0565b818073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a5d57600080fd5b505af1158015612a71573d6000803e3d6000fd5b50505050612aa4612a8d612a84856133a5565b6040015161349c565b612a96856131d5565b6134ae90919063ffffffff16565b915050919050565b600082828073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401612ae991906154a4565b600060405180830381600087803b158015612b0357600080fd5b505af1158015612b17573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff166358ca6f98866040518263ffffffff1660e01b8152600401612b5491906154a4565b602060405180830381865afa158015612b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b9591906158bb565b9250505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60608085858073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b8152600401612c0191906154a4565b600060405180830381600087803b158015612c1b57600080fd5b505af1158015612c2f573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636fc6407c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc4919061568b565b90508686905067ffffffffffffffff811115612ce357612ce2614347565b5b604051908082528060200260200182016040528015612d115781602001602082028036833780820191505090505b5094508686905067ffffffffffffffff811115612d3157612d30614347565b5b604051908082528060200260200182016040528015612d5f5781602001602082028036833780820191505090505b50935060005b87879050811015612f255760008273ffffffffffffffffffffffffffffffffffffffff16632c3e50e58b8b8b86818110612da257612da16154ec565b5b905060200201356040518363ffffffff1660e01b8152600401612dc6929190615721565b60c060405180830381865afa158015612de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e079190615802565b90508060800151878381518110612e2157612e206154ec565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff166366f8162e8b8d8c8c87818110612e8c57612e8b6154ec565b5b905060200201356040518463ffffffff1660e01b8152600401612eb19392919061582f565b602060405180830381865afa158015612ece573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ef29190615312565b868381518110612f0557612f046154ec565b5b602002602001018181525050508080612f1d90615605565b915050612d65565b5050505094509492505050565b600080828073ffffffffffffffffffffffffffffffffffffffff166311da60b46040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612f7e57600080fd5b505af1158015612f92573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613003573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130279190615968565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632d809cb6876040518263ffffffff1660e01b815260040161308491906156d9565b602060405180830381865afa1580156130a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c59190615968565b90506130cf61287e565b73ffffffffffffffffffffffffffffffffffffffff1663faaebd21836040518263ffffffff1660e01b815260040161310791906154a4565b602060405180830381865afa158015613124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131489190615312565b945061315261287e565b73ffffffffffffffffffffffffffffffffffffffff1663faaebd21826040518263ffffffff1660e01b815260040161318a91906154a4565b602060405180830381865afa1580156131a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131cb9190615312565b9350505050915091565b6131dd6135a0565b8173ffffffffffffffffffffffffffffffffffffffff16639a427d038373ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613244573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326891906156f4565b6040518263ffffffff1660e01b8152600401613284919061552a565b6040805180830381865afa1580156132a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c491906154bf565b9050919050565b600060026132d984846134ff565b14905092915050565b600060016132f084846134ff565b14905092915050565b600081670de0b6b3a7640000846133109190615995565b61331a9190615a1e565b905092915050565b6000670de0b6b3a764000082846133399190615995565b6133439190615a1e565b905092915050565b6000613357838361353d565b905092915050565b6000670de0b6b3a7640000826133759190615a4f565b9050919050565b6000670de0b6b3a764000082846133939190615a4f565b61339d9190615b66565b905092915050565b6133ad613767565b8173ffffffffffffffffffffffffffffffffffffffff16637ece075d8373ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613414573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343891906156f4565b6040518263ffffffff1660e01b8152600401613454919061552a565b606060405180830381865afa158015613471573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349591906155a9565b9050919050565b60006134a782613557565b9050919050565b6134b66135a0565b60405180604001604052806134d884866000015161332290919063ffffffff16565b81526020016134f484866020015161332290919063ffffffff16565b815250905092915050565b60008060008484915091508082111561351d57600292505050613537565b8082101561353057600092505050613537565b6001925050505b92915050565b60008183101561354d578161354f565b825b905092915050565b60008082121561356a578160000361356c565b815b9050919050565b60405180606001604052806000815260200161358d6135a0565b815260200161359a6135a0565b81525090565b604051806040016040528060008152602001600081525090565b60405180610140016040528060608152602001606081526020016135dc613788565b8152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016136296137d2565b81525090565b604051806101600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200161368b613573565b81526020016136986135a0565b81526020016000151581526020016000151581526020016136b76135a0565b815260200160008152602001600081525090565b604051806101a001604052806136df6135ba565b8152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001613717613767565b8152602001600081526020016000815260200160008152602001613739613573565b81526020016137466135a0565b815260200160008152602001600081526020016137616135a0565b81525090565b60405180606001604052806000815260200160008152602001600081525090565b6040518060600160405280600060018111156137a7576137a6613ae8565b5b8152602001600060018111156137c0576137bf613ae8565b5b8152602001600061ffff191681525090565b60405180608001604052806000600f0b81526020016000600f0b81526020016000600f0b815260200160006fffffffffffffffffffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061385482613829565b9050919050565b600061386682613849565b9050919050565b6138768161385b565b811461388157600080fd5b50565b6000813590506138938161386d565b92915050565b6000602082840312156138af576138ae61381f565b5b60006138bd84828501613884565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156139005780820151818401526020810190506138e5565b8381111561390f576000848401525b50505050565b6000601f19601f8301169050919050565b6000613931826138c6565b61393b81856138d1565b935061394b8185602086016138e2565b61395481613915565b840191505092915050565b600060208201905081810360008301526139798184613926565b905092915050565b6000819050919050565b61399481613981565b82525050565b6000819050919050565b60006139bf6139ba6139b584613981565b61399a565b613981565b9050919050565b6139cf816139a4565b82525050565b6040820160008201516139eb60008501826139c6565b5060208201516139fe60208501826139c6565b50505050565b60a082016000820151613a1a600085018261398b565b506020820151613a2d60208501826139d5565b506040820151613a4060608501826139d5565b50505050565b604082016000820151613a5c60008501826139c6565b506020820151613a6f60208501826139c6565b50505050565b600060e082019050613a8a6000830185613a04565b613a9760a0830184613a46565b9392505050565b600082825260208201905092915050565b6000613aba826138c6565b613ac48185613a9e565b9350613ad48185602086016138e2565b613add81613915565b840191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110613b2857613b27613ae8565b5b50565b6000819050613b3982613b17565b919050565b6000613b4982613b2b565b9050919050565b613b5981613b3e565b82525050565b60028110613b7057613b6f613ae8565b5b50565b6000819050613b8182613b5f565b919050565b6000613b9182613b73565b9050919050565b613ba181613b86565b82525050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000082169050919050565b613bdc81613ba7565b82525050565b606082016000820151613bf86000850182613b50565b506020820151613c0b6020850182613b98565b506040820151613c1e6040850182613bd3565b50505050565b6000613c3f613c3a613c3584613829565b61399a565b613829565b9050919050565b6000613c5182613c24565b9050919050565b6000613c6382613c46565b9050919050565b613c7381613c58565b82525050565b600081600f0b9050919050565b6000613ca1613c9c613c9784613c79565b61399a565b613c79565b9050919050565b613cb181613c86565b82525050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6000613cee613ce9613ce484613cb7565b61399a565b613cb7565b9050919050565b613cfe81613cd3565b82525050565b608082016000820151613d1a6000850182613ca8565b506020820151613d2d6020850182613ca8565b506040820151613d406040850182613ca8565b506060820151613d536060850182613cf5565b50505050565b60006101e0830160008301518482036000860152613d778282613aaf565b91505060208301518482036020860152613d918282613aaf565b9150506040830151613da66040860182613be2565b506060830151613db960a0860182613c6a565b506080830151613dcc60c08601826139c6565b5060a0830151613ddf60e08601826139c6565b5060c0830151613df36101008601826139c6565b5060e0830151613e076101208601826139c6565b50610100830151613e1c6101408601826139c6565b50610120830151613e31610160860182613d04565b508091505092915050565b60006020820190508181036000830152613e568184613d59565b905092915050565b6000819050919050565b6000613e83613e7e613e7984613e5e565b61399a565b613e5e565b9050919050565b613e9381613e68565b82525050565b6000602082019050613eae6000830184613e8a565b92915050565b600060a082019050613ec96000830184613a04565b92915050565b613ed881613849565b8114613ee357600080fd5b50565b600081359050613ef581613ecf565b92915050565b60008060408385031215613f1257613f1161381f565b5b6000613f2085828601613ee6565b9250506020613f3185828601613884565b9150509250929050565b613f4481613849565b82525050565b60a082016000820151613f60600085018261398b565b506020820151613f7360208501826139d5565b506040820151613f8660608501826139d5565b50505050565b60008115159050919050565b613fa181613f8c565b82525050565b61022082016000820151613fbe6000850182613f3b565b506020820151613fd16020850182613f3b565b506040820151613fe460408501826139c6565b506060820151613ff760608501826139c6565b50608082015161400a6080850182613f4a565b5060a082015161401e6101208501826139d5565b5060c0820151614032610160850182613f98565b5060e0820151614046610180850182613f98565b5061010082015161405b6101a08501826139d5565b506101208201516140706101e08501826139c6565b506101408201516140856102008501826139c6565b50505050565b6000610220820190506140a16000830184613fa7565b92915050565b6140b0816139a4565b82525050565b60006020820190506140cb60008301846140a7565b92915050565b60006101e08301600083015184820360008601526140ef8282613aaf565b915050602083015184820360208601526141098282613aaf565b915050604083015161411e6040860182613be2565b50606083015161413160a0860182613c6a565b50608083015161414460c08601826139c6565b5060a083015161415760e08601826139c6565b5060c083015161416b6101008601826139c6565b5060e083015161417f6101208601826139c6565b506101008301516141946101408601826139c6565b506101208301516141a9610160860182613d04565b508091505092915050565b6141bd81613e68565b82525050565b6060820160008201516141d9600085018261398b565b5060208201516141ec602085018261398b565b5060408201516141ff60408501826141b4565b50505050565b60006102a083016000830151848203600086015261422382826140d1565b91505060208301516142386020860182613f3b565b50604083015161424b60408601826141b4565b50606083015161425e60608601826141b4565b50608083015161427160808601826141c3565b5060a083015161428460e08601826139c6565b5060c08301516142986101008601826139c6565b5060e08301516142ac6101208601826139c6565b506101008301516142c1610140860182613f4a565b506101208301516142d66101e08601826139d5565b506101408301516142eb6102208601826139c6565b506101608301516143006102408601826139c6565b506101808301516143156102608601826139d5565b508091505092915050565b6000602082019050818103600083015261433a8184614205565b905092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61437f82613915565b810181811067ffffffffffffffff8211171561439e5761439d614347565b5b80604052505050565b60006143b1613815565b90506143bd8282614376565b919050565b600067ffffffffffffffff8211156143dd576143dc614347565b5b602082029050602081019050919050565b600080fd5b6143fc81613981565b811461440757600080fd5b50565b600081359050614419816143f3565b92915050565b600061443261442d846143c2565b6143a7565b90508083825260208201905060208402830185811115614455576144546143ee565b5b835b8181101561447e578061446a888261440a565b845260208401935050602081019050614457565b5050509392505050565b600082601f83011261449d5761449c614342565b5b81356144ad84826020860161441f565b91505092915050565b600080604083850312156144cd576144cc61381f565b5b60006144db85828601613884565b925050602083013567ffffffffffffffff8111156144fc576144fb613824565b5b61450885828601614488565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061454a83836141c3565b60608301905092915050565b6000602082019050919050565b600061456e82614512565b614578818561451d565b93506145838361452e565b8060005b838110156145b457815161459b888261453e565b97506145a683614556565b925050600181019050614587565b5085935050505092915050565b600060208201905081810360008301526145db8184614563565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600061461a82613c46565b9050919050565b61462a8161460f565b82525050565b600061463c8383614621565b60208301905092915050565b6000602082019050919050565b6000614660826145e3565b61466a81856145ee565b9350614675836145ff565b8060005b838110156146a657815161468d8882614630565b975061469883614648565b925050600181019050614679565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006146eb83836139c6565b60208301905092915050565b6000602082019050919050565b600061470f826146b3565b61471981856146be565b9350614724836146cf565b8060005b8381101561475557815161473c88826146df565b9750614747836146f7565b925050600181019050614728565b5085935050505092915050565b6000604082019050818103600083015261477c8185614655565b905081810360208301526147908184614704565b90509392505050565b6147a281613f8c565b82525050565b60006020820190506147bd6000830184614799565b92915050565b6147cc81613981565b81146147d757600080fd5b50565b6000813590506147e9816147c3565b92915050565b6000806000606084860312156148085761480761381f565b5b600061481686828701613ee6565b935050602061482786828701613884565b9250506040614838868287016147da565b9150509250925092565b606082016000820151614858600085018261398b565b50602082015161486b602085018261398b565b50604082015161487e60408501826141b4565b50505050565b60006060820190506148996000830184614842565b92915050565b600067ffffffffffffffff8211156148ba576148b9614347565b5b602082029050602081019050919050565b60006148de6148d98461489f565b6143a7565b90508083825260208201905060208402830185811115614901576149006143ee565b5b835b8181101561492a57806149168882613884565b845260208401935050602081019050614903565b5050509392505050565b600082601f83011261494957614948614342565b5b81356149598482602086016148cb565b91505092915050565b600080604083850312156149795761497861381f565b5b600061498785828601613ee6565b925050602083013567ffffffffffffffff8111156149a8576149a7613824565b5b6149b485828601614934565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61022082016000820151614a016000850182613f3b565b506020820151614a146020850182613f3b565b506040820151614a2760408501826139c6565b506060820151614a3a60608501826139c6565b506080820151614a4d6080850182613f4a565b5060a0820151614a616101208501826139d5565b5060c0820151614a75610160850182613f98565b5060e0820151614a89610180850182613f98565b50610100820151614a9e6101a08501826139d5565b50610120820151614ab36101e08501826139c6565b50610140820151614ac86102008501826139c6565b50505050565b6000614ada83836149ea565b6102208301905092915050565b6000602082019050919050565b6000614aff826149be565b614b0981856149c9565b9350614b14836149da565b8060005b83811015614b45578151614b2c8882614ace565b9750614b3783614ae7565b925050600181019050614b18565b5085935050505092915050565b60006020820190508181036000830152614b6c8184614af4565b905092915050565b600080fd5b60008083601f840112614b8f57614b8e614342565b5b8235905067ffffffffffffffff811115614bac57614bab614b74565b5b602083019150836020820283011115614bc857614bc76143ee565b5b9250929050565b60008060208385031215614be657614be561381f565b5b600083013567ffffffffffffffff811115614c0457614c03613824565b5b614c1085828601614b79565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006102a0830160008301518482036000860152614c6682826140d1565b9150506020830151614c7b6020860182613f3b565b506040830151614c8e60408601826141b4565b506060830151614ca160608601826141b4565b506080830151614cb460808601826141c3565b5060a0830151614cc760e08601826139c6565b5060c0830151614cdb6101008601826139c6565b5060e0830151614cef6101208601826139c6565b50610100830151614d04610140860182613f4a565b50610120830151614d196101e08601826139d5565b50610140830151614d2e6102208601826139c6565b50610160830151614d436102408601826139c6565b50610180830151614d586102608601826139d5565b508091505092915050565b6000614d6f8383614c48565b905092915050565b6000602082019050919050565b6000614d8f82614c1c565b614d998185614c27565b935083602082028501614dab85614c38565b8060005b85811015614de75784840389528151614dc88582614d63565b9450614dd383614d77565b925060208a01995050600181019050614daf565b50829750879550505050505092915050565b60006020820190508181036000830152614e138184614d84565b905092915050565b6000604082019050614e306000830184613a46565b92915050565b6000614e4182613c46565b9050919050565b614e5181614e36565b82525050565b6000602082019050614e6c6000830184614e48565b92915050565b6000614e7d82613c46565b9050919050565b614e8d81614e72565b82525050565b6000602082019050614ea86000830184614e84565b92915050565b60008083601f840112614ec457614ec3614342565b5b8235905067ffffffffffffffff811115614ee157614ee0614b74565b5b602083019150836020820283011115614efd57614efc6143ee565b5b9250929050565b60008060008060608587031215614f1e57614f1d61381f565b5b6000614f2c87828801613ee6565b9450506020614f3d87828801613884565b935050604085013567ffffffffffffffff811115614f5e57614f5d613824565b5b614f6a87828801614eae565b925092505092959194509250565b6000604082019050614f8d60008301856140a7565b614f9a60208301846140a7565b9392505050565b600080fd5b600067ffffffffffffffff821115614fc157614fc0614347565b5b614fca82613915565b9050602081019050919050565b6000614fea614fe584614fa6565b6143a7565b90508281526020810184848401111561500657615005614fa1565b5b6150118482856138e2565b509392505050565b600082601f83011261502e5761502d614342565b5b815161503e848260208601614fd7565b91505092915050565b60006020828403121561505d5761505c61381f565b5b600082015167ffffffffffffffff81111561507b5761507a613824565b5b61508784828501615019565b91505092915050565b600080fd5b6000815190506150a4816143f3565b92915050565b6000815190506150b9816147c3565b92915050565b6000604082840312156150d5576150d4615090565b5b6150df60406143a7565b905060006150ef848285016150aa565b6000830152506020615103848285016150aa565b60208301525092915050565b600060a0828403121561512557615124615090565b5b61512f60606143a7565b9050600061513f84828501615095565b6000830152506020615153848285016150bf565b6020830152506060615167848285016150bf565b60408301525092915050565b600060a082840312156151895761518861381f565b5b60006151978482850161510f565b91505092915050565b600281106151ad57600080fd5b50565b6000815190506151bf816151a0565b92915050565b600281106151d257600080fd5b50565b6000815190506151e4816151c5565b92915050565b6151f381613ba7565b81146151fe57600080fd5b50565b600081519050615210816151ea565b92915050565b60006060828403121561522c5761522b615090565b5b61523660606143a7565b90506000615246848285016151b0565b600083015250602061525a848285016151d5565b602083015250604061526e84828501615201565b60408301525092915050565b6000606082840312156152905761528f61381f565b5b600061529e84828501615216565b91505092915050565b60006152b282613849565b9050919050565b6152c2816152a7565b81146152cd57600080fd5b50565b6000815190506152df816152b9565b92915050565b6000602082840312156152fb576152fa61381f565b5b6000615309848285016152d0565b91505092915050565b6000602082840312156153285761532761381f565b5b6000615336848285016150aa565b91505092915050565b61534881613c79565b811461535357600080fd5b50565b6000815190506153658161533f565b92915050565b61537481613cb7565b811461537f57600080fd5b50565b6000815190506153918161536b565b92915050565b6000608082840312156153ad576153ac615090565b5b6153b760806143a7565b905060006153c784828501615356565b60008301525060206153db84828501615356565b60208301525060406153ef84828501615356565b604083015250606061540384828501615382565b60608301525092915050565b6000608082840312156154255761542461381f565b5b600061543384828501615397565b91505092915050565b61544581613e5e565b811461545057600080fd5b50565b6000815190506154628161543c565b92915050565b60006020828403121561547e5761547d61381f565b5b600061548c84828501615453565b91505092915050565b61549e81613849565b82525050565b60006020820190506154b96000830184615495565b92915050565b6000604082840312156154d5576154d461381f565b5b60006154e3848285016150bf565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61552481613981565b82525050565b600060208201905061553f600083018461551b565b92915050565b60006060828403121561555b5761555a615090565b5b61556560606143a7565b9050600061557584828501615095565b600083015250602061558984828501615095565b602083015250604061559d84828501615453565b60408301525092915050565b6000606082840312156155bf576155be61381f565b5b60006155cd84828501615545565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061561082613981565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615642576156416155d6565b5b600182019050919050565b600061565882613849565b9050919050565b6156688161564d565b811461567357600080fd5b50565b6000815190506156858161565f565b92915050565b6000602082840312156156a1576156a061381f565b5b60006156af84828501615676565b91505092915050565b60006156c382613c46565b9050919050565b6156d3816156b8565b82525050565b60006020820190506156ee60008301846156ca565b92915050565b60006020828403121561570a5761570961381f565b5b600061571884828501615095565b91505092915050565b600060408201905061573660008301856156ca565b615743602083018461551b565b9392505050565b61575381613849565b811461575e57600080fd5b50565b6000815190506157708161574a565b92915050565b600060c0828403121561578c5761578b615090565b5b61579660a06143a7565b905060006157a684828501615095565b60008301525060206157ba848285016150bf565b60208301525060606157ce84828501615095565b60408301525060806157e284828501615095565b60608301525060a06157f684828501615761565b60808301525092915050565b600060c082840312156158185761581761381f565b5b600061582684828501615776565b91505092915050565b600060608201905061584460008301866156ca565b6158516020830185615495565b61585e604083018461551b565b949350505050565b600060408201905061587b6000830185615495565b61588860208301846156ca565b9392505050565b61589881613f8c565b81146158a357600080fd5b50565b6000815190506158b58161588f565b92915050565b6000602082840312156158d1576158d061381f565b5b60006158df848285016158a6565b91505092915050565b60006158f382613849565b9050919050565b615903816158e8565b811461590e57600080fd5b50565b600081519050615920816158fa565b92915050565b60006020828403121561593c5761593b61381f565b5b600061594a84828501615911565b91505092915050565b60008151905061596281613ecf565b92915050565b60006020828403121561597e5761597d61381f565b5b600061598c84828501615953565b91505092915050565b60006159a082613981565b91506159ab83613981565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156159e4576159e36155d6565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000615a2982613981565b9150615a3483613981565b925082615a4457615a436159ef565b5b828204905092915050565b6000615a5a82613e5e565b9150615a6583613e5e565b9250827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482116000841360008413161615615aa457615aa36155d6565b5b817f80000000000000000000000000000000000000000000000000000000000000000583126000841260008413161615615ae157615ae06155d6565b5b827f80000000000000000000000000000000000000000000000000000000000000000582126000841360008412161615615b1e57615b1d6155d6565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0582126000841260008412161615615b5b57615b5a6155d6565b5b828202905092915050565b6000615b7182613e5e565b9150615b7c83613e5e565b925082615b8c57615b8b6159ef565b5b600160000383147f800000000000000000000000000000000000000000000000000000000000000083141615615bc557615bc46155d6565b5b82820590509291505056fea2646970667358221220e650dd4b391677aa40c90d4f7f374c06bf08ad9fbde8ed1f78d106103771142064736f6c634300080f0033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "atVersions(address,uint256[])": {
        "params": {
          "product": "Product address",
          "versions": "Oracle versions to query"
        },
        "returns": {
          "prices": "Product prices at specified versions"
        }
      },
      "collateral()": {
        "returns": {
          "_0": "Protocol collateral address"
        }
      },
      "collateral(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Total collateral for product"
        }
      },
      "collateral(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "User deposited collateral for product"
        }
      },
      "constructor": {
        "params": {
          "_controller": "Protocol controller address"
        }
      },
      "dailyRate(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Product current funding extrapolated to a daily rate"
        }
      },
      "exposure(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "User's exposure (openInterest * utilization) after settle"
        }
      },
      "fees(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "productFees": "fees accrued by the product owner",
          "protocolFees": "fees accrued by the protocol"
        }
      },
      "fees(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "sum of all fees accrued by the account"
        }
      },
      "globalPosition(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Product pre-position",
          "_1": "Product position"
        }
      },
      "info(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_info": "of the product"
        }
      },
      "latestVersion(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Product latest price"
        }
      },
      "liquidatable(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "Whether or not the user's position eligible to be liquidated"
        }
      },
      "maintenance(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "Maximum of user maintenance, and maintenanceNext"
        }
      },
      "maintenanceRequired(address,address,uint256)": {
        "params": {
          "account": "Account address",
          "positionSize": "size of position for maintenance calculation",
          "product": "Product address"
        },
        "returns": {
          "_0": "Maintenance required for position in product"
        }
      },
      "name(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Name of the product"
        }
      },
      "openInterest(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Product maker and taker position multiplied by latest price after settle"
        }
      },
      "openInterest(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "User's maker or taker position multiplied by latest price after settle"
        }
      },
      "position(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "product position"
        }
      },
      "position(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "User position"
        }
      },
      "pre(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Product pre-position"
        }
      },
      "pre(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "User pre-position"
        }
      },
      "rate(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Product current funding rate"
        }
      },
      "shortfall(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Total shortfall for product"
        }
      },
      "snapshot(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Snapshot for the product after settle"
        }
      },
      "snapshot(address,address)": {
        "params": {
          "account": "User addresses",
          "product": "Product address"
        },
        "returns": {
          "_0": "UserSnapshot for the product after settle"
        }
      },
      "snapshots(address,address[])": {
        "params": {
          "account": "User addresses",
          "productAddresses": "Product addresses"
        },
        "returns": {
          "_0": "UserSnapshot for each product after settle"
        }
      },
      "snapshots(address[])": {
        "params": {
          "productAddresses": "Product addresses"
        },
        "returns": {
          "_0": "Snapshot for each product after settle"
        }
      },
      "symbol(address)": {
        "params": {
          "product": "Product address"
        },
        "returns": {
          "_0": "Symbol of the product"
        }
      },
      "unclaimedIncentiveRewards(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "amounts": "Token amounts of unclaimed incentive rewards for given product",
          "tokens": "Token addresses of unclaimed incentive rewards for given product"
        }
      },
      "unclaimedIncentiveRewards(address,address,uint256[])": {
        "params": {
          "account": "Account address",
          "product": "Product address",
          "programIds": "Program IDs to query"
        },
        "returns": {
          "amounts": "Token amounts of unclaimed incentive rewards for given program IDs",
          "tokens": "Token addresses of unclaimed incentive rewards for given program IDs"
        }
      },
      "userPosition(address,address)": {
        "params": {
          "account": "Account address",
          "product": "Product address"
        },
        "returns": {
          "_0": "User pre-position",
          "_1": "User position"
        }
      }
    },
    "stateVariables": {
      "controller": {
        "return": "Protocol controller",
        "returns": {
          "_0": "Protocol controller"
        }
      }
    },
    "title": "Lens contract to conveniently pull protocol data",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "atVersions(address,uint256[])": {
        "notice": "Prices of product at specified versions after settle"
      },
      "collateral()": {
        "notice": "Protocol collateral address"
      },
      "collateral(address)": {
        "notice": "Product total collateral amount after settle"
      },
      "collateral(address,address)": {
        "notice": "User collateral amount for product after settle"
      },
      "controller()": {
        "notice": "Protocol controller"
      },
      "dailyRate(address)": {
        "notice": "Product funding extrapolated to a daily rate after settle"
      },
      "exposure(address,address)": {
        "notice": "User's exposure in product after settle"
      },
      "fees(address)": {
        "notice": "Fees accumulated by product and protocol treasuries after settle"
      },
      "fees(address,address)": {
        "notice": "Fees accumulated by account after settle"
      },
      "globalPosition(address)": {
        "notice": "Product pre-position and position after settle"
      },
      "info(address)": {
        "notice": "Returns the info of the provided `product`"
      },
      "latestVersion(address)": {
        "notice": "Current price of product after settle"
      },
      "liquidatable(address,address)": {
        "notice": "User liquidatble status for product after settle"
      },
      "maintenance(address,address)": {
        "notice": "User maintenance amount for product after settle"
      },
      "maintenanceRequired(address,address,uint256)": {
        "notice": "User's maintenance required for position size in product after settle"
      },
      "name(address)": {
        "notice": "Returns the name of the provided `product`"
      },
      "openInterest(address)": {
        "notice": "Product total open interest after settle"
      },
      "openInterest(address,address)": {
        "notice": "User's open interest in product after settle"
      },
      "position(address)": {
        "notice": "Product position after settle"
      },
      "position(address,address)": {
        "notice": "User position for product after settle"
      },
      "pre(address)": {
        "notice": "Product pre position after settle"
      },
      "pre(address,address)": {
        "notice": "User pre position for product after settle"
      },
      "rate(address)": {
        "notice": "Product funding rate after settle"
      },
      "shortfall(address)": {
        "notice": "Product total shortfall amount after settle"
      },
      "snapshot(address)": {
        "notice": "Returns the snapshot of the provided `product`"
      },
      "snapshot(address,address)": {
        "notice": "Returns the user snapshot for the provided `product`"
      },
      "snapshots(address,address[])": {
        "notice": "Returns the user snapshots for the provided `productAddresses`"
      },
      "snapshots(address[])": {
        "notice": "Returns the snapshots of the provided `productAddresses`"
      },
      "symbol(address)": {
        "notice": "Returns the symbol of the provided `product`"
      },
      "unclaimedIncentiveRewards(address,address)": {
        "notice": "User's unclaimed rewards for all programs for product after settle"
      },
      "unclaimedIncentiveRewards(address,address,uint256[])": {
        "notice": "User's unclaimed rewards for provided programs for product after settle"
      },
      "userPosition(address,address)": {
        "notice": "User pre-position and position for product after settle"
      }
    },
    "notice": "All functions should be called using `callStatic`",
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}
