{
  "address": "0xa5492624F46F7ef346BfC46A0fB364eBa3b1f525",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "value",
          "type": "uint256"
        }
      ],
      "name": "Fixed18OverflowError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "IncentivizerBatchClaimArgumentMismatchError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "IncentivizerInvalidProgramError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "IncentivizerNotAllowedError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "IncentivizerNotProgramOwnerError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "IncentivizerTooManyProgramsError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidControllerError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "operator",
          "type": "address"
        }
      ],
      "name": "NotAccountOrMultiInvokerError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "NotCollateralError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "coordinatorId",
          "type": "uint256"
        }
      ],
      "name": "NotOwnerError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "NotProductError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "PausedError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ProgramInvalidDurationError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ProgramInvalidStartError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "int256",
          "name": "value",
          "type": "int256"
        }
      ],
      "name": "UFixed18UnderflowError",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "version",
          "type": "uint256"
        }
      ],
      "name": "UInitializableAlreadyInitializedError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "UInitializableNotInitializingError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "UInitializableZeroVersionError",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "UReentrancyGuardReentrantCallError",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "UFixed18",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "Claim",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "Token18",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "UFixed18",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "FeeClaim",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "version",
          "type": "uint256"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "version",
          "type": "uint256"
        }
      ],
      "name": "ProgramComplete",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        },
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "coordinatorId",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "amount",
              "type": "tuple"
            },
            {
              "internalType": "uint256",
              "name": "start",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "duration",
              "type": "uint256"
            },
            {
              "internalType": "Token18",
              "name": "token",
              "type": "address"
            }
          ],
          "indexed": false,
          "internalType": "struct ProgramInfo",
          "name": "programInfo",
          "type": "tuple"
        },
        {
          "indexed": false,
          "internalType": "UFixed18",
          "name": "programFeeAmount",
          "type": "uint256"
        }
      ],
      "name": "ProgramCreated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "version",
          "type": "uint256"
        }
      ],
      "name": "ProgramStarted",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        }
      ],
      "name": "active",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "available",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256[]",
          "name": "programIds",
          "type": "uint256[]"
        }
      ],
      "name": "claim",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct[]",
          "name": "products",
          "type": "address[]"
        },
        {
          "internalType": "uint256[][]",
          "name": "programIds",
          "type": "uint256[][]"
        }
      ],
      "name": "claim",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "Token18[]",
          "name": "tokens",
          "type": "address[]"
        }
      ],
      "name": "claimFee",
      "outputs": [],
      "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": "claimFor",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "complete",
      "outputs": [],
      "stateMutability": "nonpayable",
      "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": "count",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "coordinatorId",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "amount",
              "type": "tuple"
            },
            {
              "internalType": "uint256",
              "name": "start",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "duration",
              "type": "uint256"
            },
            {
              "internalType": "Token18",
              "name": "token",
              "type": "address"
            }
          ],
          "internalType": "struct ProgramInfo",
          "name": "programInfo",
          "type": "tuple"
        }
      ],
      "name": "create",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "Token18",
          "name": "",
          "type": "address"
        }
      ],
      "name": "fees",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IController",
          "name": "controller_",
          "type": "address"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "programInfos",
      "outputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "coordinatorId",
              "type": "uint256"
            },
            {
              "components": [
                {
                  "internalType": "UFixed18",
                  "name": "maker",
                  "type": "uint256"
                },
                {
                  "internalType": "UFixed18",
                  "name": "taker",
                  "type": "uint256"
                }
              ],
              "internalType": "struct Position",
              "name": "amount",
              "type": "tuple"
            },
            {
              "internalType": "uint256",
              "name": "start",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "duration",
              "type": "uint256"
            },
            {
              "internalType": "Token18",
              "name": "token",
              "type": "address"
            }
          ],
          "internalType": "struct ProgramInfo",
          "name": "",
          "type": "tuple"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "version",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "timestamp",
              "type": "uint256"
            },
            {
              "internalType": "Fixed18",
              "name": "price",
              "type": "int256"
            }
          ],
          "internalType": "struct IOracleProvider.OracleVersion",
          "name": "currentOracleVersion",
          "type": "tuple"
        }
      ],
      "name": "sync",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "components": [
            {
              "internalType": "uint256",
              "name": "version",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "timestamp",
              "type": "uint256"
            },
            {
              "internalType": "Fixed18",
              "name": "price",
              "type": "int256"
            }
          ],
          "internalType": "struct IOracleProvider.OracleVersion",
          "name": "currentOracleVersion",
          "type": "tuple"
        }
      ],
      "name": "syncAccount",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "treasury",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "unclaimed",
      "outputs": [
        {
          "internalType": "UFixed18",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "versionComplete",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IProduct",
          "name": "product",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "programId",
          "type": "uint256"
        }
      ],
      "name": "versionStarted",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0x0a1b0cb08660ced65fb133b7f4c85e1cc070ecb30d6ed424dfa5f95ef7470248",
  "receipt": {
    "to": null,
    "from": "0x66a7fDB96C583c59597de16d8b2B989231415339",
    "contractAddress": "0xa5492624F46F7ef346BfC46A0fB364eBa3b1f525",
    "transactionIndex": 146,
    "gasUsed": "5088589",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xa0a776a63ddd16b625a6b06f99acb654ae60da6cc3f0c655463e29f1ac78b25d",
    "transactionHash": "0x0a1b0cb08660ced65fb133b7f4c85e1cc070ecb30d6ed424dfa5f95ef7470248",
    "logs": [],
    "blockNumber": 16092295,
    "cumulativeGasUsed": "18294337",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "numDeployments": 1,
  "solcInputHash": "67765cb14648b58243a15d35477dbc39",
  "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Fixed18OverflowError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncentivizerBatchClaimArgumentMismatchError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"IncentivizerInvalidProgramError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"IncentivizerNotAllowedError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"IncentivizerNotProgramOwnerError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncentivizerTooManyProgramsError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidControllerError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"NotAccountOrMultiInvokerError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotCollateralError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"coordinatorId\",\"type\":\"uint256\"}],\"name\":\"NotOwnerError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"NotProductError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProgramInvalidDurationError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProgramInvalidStartError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"value\",\"type\":\"int256\"}],\"name\":\"UFixed18UnderflowError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"UInitializableAlreadyInitializedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UInitializableNotInitializingError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UInitializableZeroVersionError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UReentrancyGuardReentrantCallError\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"Token18\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeeClaim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"ProgramComplete\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"coordinatorId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"amount\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"Token18\",\"name\":\"token\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct ProgramInfo\",\"name\":\"programInfo\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"programFeeAmount\",\"type\":\"uint256\"}],\"name\":\"ProgramCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"ProgramStarted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"}],\"name\":\"active\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"available\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"programIds\",\"type\":\"uint256[]\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct[]\",\"name\":\"products\",\"type\":\"address[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"programIds\",\"type\":\"uint256[][]\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"Token18[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"claimFee\",\"outputs\":[],\"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\":\"claimFor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"complete\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"coordinatorId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"amount\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"Token18\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"struct ProgramInfo\",\"name\":\"programInfo\",\"type\":\"tuple\"}],\"name\":\"create\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"Token18\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"fees\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IController\",\"name\":\"controller_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"programInfos\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"coordinatorId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"UFixed18\",\"name\":\"maker\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"taker\",\"type\":\"uint256\"}],\"internalType\":\"struct Position\",\"name\":\"amount\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"Token18\",\"name\":\"token\",\"type\":\"address\"}],\"internalType\":\"struct ProgramInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"Fixed18\",\"name\":\"price\",\"type\":\"int256\"}],\"internalType\":\"struct IOracleProvider.OracleVersion\",\"name\":\"currentOracleVersion\",\"type\":\"tuple\"}],\"name\":\"sync\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"Fixed18\",\"name\":\"price\",\"type\":\"int256\"}],\"internalType\":\"struct IOracleProvider.OracleVersion\",\"name\":\"currentOracleVersion\",\"type\":\"tuple\"}],\"name\":\"syncAccount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"unclaimed\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"versionComplete\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"programId\",\"type\":\"uint256\"}],\"name\":\"versionStarted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"active(address)\":{\"params\":{\"product\":\"Product to check for\"},\"returns\":{\"_0\":\"Number of active programs\"}},\"available(address,uint256)\":{\"params\":{\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"Available rewards for `programId`\"}},\"claim(address,uint256[])\":{\"params\":{\"product\":\"Product to claim rewards for\",\"programIds\":\"Programs to claim rewards for\"}},\"claim(address[],uint256[][])\":{\"params\":{\"products\":\"Products to claim rewards for\",\"programIds\":\"Programs to claim rewards for\"}},\"claimFee(address[])\":{\"params\":{\"tokens\":\"Tokens to claim fees for\"}},\"claimFor(address,address,uint256[])\":{\"params\":{\"account\":\"Account to claim rewards for\",\"product\":\"Product to claim rewards for\",\"programIds\":\"Programs to claim rewards for\"}},\"complete(address,uint256)\":{\"details\":\"Must be called as the program owner\",\"params\":{\"product\":\"Product that the program is running on\",\"programId\":\"Program to complete early\"}},\"count(address)\":{\"params\":{\"product\":\"Product to check for\"},\"returns\":{\"_0\":\"Number of programs (inactive or active)\"}},\"create(address,(uint256,(uint256,uint256),uint256,uint256,address))\":{\"details\":\"Must be called as the product or protocol owner\",\"params\":{\"product\":\"The product to create the new program on\",\"programInfo\":\"Parameters for the new program\"},\"returns\":{\"programId\":\"New program's ID\"}},\"initialize(address)\":{\"details\":\"Must be called atomically as part of the upgradeable proxy deployment to      avoid front-running\",\"params\":{\"controller_\":\"Factory contract address\"}},\"owner(address,uint256)\":{\"params\":{\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"The owner of `programId`\"}},\"programInfos(address,uint256)\":{\"params\":{\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"Program info\"}},\"sync((uint256,uint256,int256))\":{\"details\":\"Called every settle() from each product\",\"params\":{\"currentOracleVersion\":\"The preloaded current oracle version\"}},\"syncAccount(address,(uint256,uint256,int256))\":{\"details\":\"Called immediately proceeding a position update in the corresponding product\",\"params\":{\"account\":\"Account to sync\",\"currentOracleVersion\":\"The preloaded current oracle version\"}},\"treasury(address,uint256)\":{\"params\":{\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"The treasury of `programId`\"}},\"unclaimed(address,address,uint256)\":{\"params\":{\"account\":\"Account to return for\",\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"`account`'s total unclaimed rewards for `programId`\"}},\"versionComplete(address,uint256)\":{\"params\":{\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"The version completed for `programId`\"}},\"versionStarted(address,uint256)\":{\"params\":{\"product\":\"Product to return for\",\"programId\":\"Program to return for\"},\"returns\":{\"_0\":\"The version started for `programId`\"}}},\"stateVariables\":{\"_products\":{\"details\":\"Product management state\"},\"fees\":{\"details\":\"Fees that have been collected, but remain unclaimed\"}},\"title\":\"Incentivizer\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"active(address)\":{\"notice\":\"Returns the quantity of active programs for a given product\"},\"available(address,uint256)\":{\"notice\":\"Returns available rewards for a specific program\"},\"claim(address,uint256[])\":{\"notice\":\"Claims all of `msg.sender`'s rewards for `product` programs\"},\"claim(address[],uint256[][])\":{\"notice\":\"Claims all of `msg.sender`'s rewards for a specific program\"},\"claimFee(address[])\":{\"notice\":\"Claims all `tokens` fees to the protocol treasury\"},\"claimFor(address,address,uint256[])\":{\"notice\":\"Claims all of `account`'s rewards for `product` programs\"},\"complete(address,uint256)\":{\"notice\":\"Completes an in-progress program early\"},\"count(address)\":{\"notice\":\"Returns the quantity of programs for a given product\"},\"create(address,(uint256,(uint256,uint256),uint256,uint256,address))\":{\"notice\":\"Creates a new incentive program\"},\"initialize(address)\":{\"notice\":\"Initializes the contract state\"},\"owner(address,uint256)\":{\"notice\":\"Returns the owner of a specific program\"},\"programInfos(address,uint256)\":{\"notice\":\"Returns program info for program `programId`\"},\"sync((uint256,uint256,int256))\":{\"notice\":\"Starts and completes programs as they become available\"},\"syncAccount(address,(uint256,uint256,int256))\":{\"notice\":\"Settles unsettled balance for `account`\"},\"treasury(address,uint256)\":{\"notice\":\"Returns the treasury of a specific program\"},\"unclaimed(address,address,uint256)\":{\"notice\":\"Returns `account`'s total unclaimed rewards for a specific program\"},\"versionComplete(address,uint256)\":{\"notice\":\"Returns the version completed for a specific program\"},\"versionStarted(address,uint256)\":{\"notice\":\"Returns the version started for a specific program\"}},\"notice\":\"Manages logic and state for all incentive programs in the protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/incentivizer/Incentivizer.sol\":\"Incentivizer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@equilibria/emptyset-batcher/batcher/Batcher.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"@equilibria/root/control/unstructured/UOwnable.sol\\\";\\nimport \\\"../interfaces/IBatcher.sol\\\";\\n\\nabstract contract Batcher is IBatcher, UOwnable {\\n    using UFixed18Lib for UFixed18;\\n    using Token18Lib for Token18;\\n    using Token6Lib for Token6;\\n\\n    IEmptySetReserve public immutable RESERVE;\\n    Token18 public immutable DSU;\\n    Token6 public immutable USDC;\\n\\n    constructor(IEmptySetReserve reserve, Token18 dsu, Token6 usdc) {\\n        RESERVE = reserve;\\n        DSU = dsu;\\n        USDC = usdc;\\n\\n        DSU.approve(address(RESERVE));\\n        USDC.approve(address(RESERVE));\\n\\n        __UOwnable__initialize();\\n    }\\n\\n    function totalBalance() public view returns (UFixed18) {\\n        return DSU.balanceOf().add(USDC.balanceOf());\\n    }\\n\\n    function wrap(UFixed18 amount, address to) external {\\n        _wrap(amount, to);\\n        emit Wrap(to, amount);\\n    }\\n\\n    function _wrap(UFixed18 amount, address to) virtual internal {\\n        USDC.pull(msg.sender, amount, true);\\n        DSU.push(to, amount);\\n    }\\n\\n    function unwrap(UFixed18 amount, address to) external {\\n        _unwrap(amount, to);\\n        emit Unwrap(to, amount);\\n    }\\n\\n    function _unwrap(UFixed18 amount, address to) virtual internal {\\n        DSU.pull(msg.sender, amount);\\n        USDC.push(to, amount);\\n    }\\n\\n    function rebalance() external {\\n        (UFixed18 usdcBalance, UFixed18 dsuBalance) = (USDC.balanceOf(), DSU.balanceOf());\\n\\n        _rebalance(USDC.balanceOf(), DSU.balanceOf());\\n\\n        (UFixed18 oldBalance, UFixed18 newBalance) = (usdcBalance.add(dsuBalance), totalBalance());\\n        if (!oldBalance.eq(newBalance)) revert BatcherBalanceMismatchError(oldBalance, newBalance);\\n\\n        emit Rebalance(usdcBalance, UFixed18Lib.ZERO);\\n    }\\n\\n    function _rebalance(UFixed18 usdcBalance, UFixed18 dsuBalance) virtual internal;\\n\\n    function close() external onlyOwner {\\n        UFixed18 usdcBalance = USDC.balanceOf();\\n        if (!usdcBalance.isZero()) RESERVE.mint(usdcBalance);\\n\\n        UFixed18 dsuBalance = DSU.balanceOf();\\n        UFixed18 repayAmount = UFixed18Lib.min(RESERVE.debt(address(this)), dsuBalance);\\n        UFixed18 returnAmount = dsuBalance.sub(repayAmount);\\n\\n        RESERVE.repay(address(this), repayAmount);\\n        if (!returnAmount.isZero()) DSU.push(address(RESERVE), dsuBalance.sub(repayAmount));\\n\\n        emit Close(dsuBalance);\\n    }\\n}\\n\\ninterface IEmptySetReserve {\\n    function debt(address borrower) external view returns (UFixed18);\\n    function repay(address borrower, UFixed18 amount) external;\\n    function mint(UFixed18 amount) external;\\n    function redeem(UFixed18 amount) external;\\n}\\n\",\"keccak256\":\"0xaa999f733fa0ff0f971027654ef9f577143bb63f6eabaaf308ccdcac5ebf5031\",\"license\":\"Apache-2.0\"},\"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\ninterface IBatcher {\\n    event Wrap(address indexed to, UFixed18 amount);\\n    event Unwrap(address indexed to, UFixed18 amount);\\n    event Rebalance(UFixed18 newMinted, UFixed18 newRedeemed);\\n    event Close(UFixed18 amount);\\n\\n    error BatcherNotImplementedError();\\n    error BatcherBalanceMismatchError(UFixed18 oldBalance, UFixed18 newBalance);\\n\\n    function totalBalance() external view returns (UFixed18);\\n    function wrap(UFixed18 amount, address to) external;\\n    function unwrap(UFixed18 amount, address to) external;\\n    function rebalance() external;\\n}\\n\",\"keccak256\":\"0x5d49c13991d92df22f77377b4ae98149bdfb588e04a084e00feec70569499c8b\",\"license\":\"Apache-2.0\"},\"@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/control/unstructured/UInitializable.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../../storage/UStorage.sol\\\";\\n\\n/**\\n * @title UInitializable\\n * @notice Library to manage the initialization lifecycle of upgradeable contracts\\n * @dev `UInitializable` allows the creation of pseudo-constructors for upgradeable contracts. One\\n *      `initializer` should be declared per top-level contract. Child contracts can use the `onlyInitializer`\\n *      modifier to tag their internal initialization functions to ensure that they can only be called\\n *      from a top-level `initializer` or a constructor.\\n */\\nabstract contract UInitializable {\\n    error UInitializableZeroVersionError();\\n    error UInitializableAlreadyInitializedError(uint256 version);\\n    error UInitializableNotInitializingError();\\n\\n    event Initialized(uint256 version);\\n\\n    /// @dev The initialized flag\\n    Uint256Storage private constant _version = Uint256Storage.wrap(keccak256(\\\"equilibria.root.UInitializable.version\\\"));\\n\\n    /// @dev The initializing flag\\n    BoolStorage private constant _initializing = BoolStorage.wrap(keccak256(\\\"equilibria.root.UInitializable.initializing\\\"));\\n\\n    /// @dev Can only be called once per version, `version` is 1-indexed\\n    modifier initializer(uint256 version) {\\n        if (version == 0) revert UInitializableZeroVersionError();\\n        if (_version.read() >= version) revert UInitializableAlreadyInitializedError(version);\\n\\n        _version.store(version);\\n        _initializing.store(true);\\n\\n        _;\\n\\n        _initializing.store(false);\\n        emit Initialized(version);\\n    }\\n\\n    /// @dev Can only be called from an initializer or constructor\\n    modifier onlyInitializer() {\\n        if (!_constructing() && !_initializing.read()) revert UInitializableNotInitializingError();\\n        _;\\n    }\\n\\n    /**\\n     * @notice Returns whether the contract is currently being constructed\\n     * @dev {Address.isContract} returns false for contracts currently in the process of being constructed\\n     * @return Whether the contract is currently being constructed\\n     */\\n    function _constructing() private view returns (bool) {\\n        return !Address.isContract(address(this));\\n    }\\n}\\n\",\"keccak256\":\"0xd2743d8fcc220ed2ccdc0bba1db0a3e107741bd5c0cac47ca8c0b5a00ba2fd7f\",\"license\":\"Apache-2.0\"},\"@equilibria/root/control/unstructured/UOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./UInitializable.sol\\\";\\nimport \\\"../../storage/UStorage.sol\\\";\\n\\n/**\\n * @title UOwnable\\n * @notice Library to manage the ownership lifecycle of upgradeable contracts.\\n * @dev This contract has been extended from the Open Zeppelin library to include an\\n *      unstructured storage pattern so that it can be safely mixed in with upgradeable\\n *      contracts without affecting their storage patterns through inheritance.\\n */\\nabstract contract UOwnable is UInitializable {\\n    event OwnerUpdated(address indexed newOwner);\\n    event PendingOwnerUpdated(address indexed newPendingOwner);\\n\\n    error UOwnableNotOwnerError(address sender);\\n    error UOwnableNotPendingOwnerError(address sender);\\n\\n    /// @dev The owner address\\n    AddressStorage private constant _owner = AddressStorage.wrap(keccak256(\\\"equilibria.root.UOwnable.owner\\\"));\\n    function owner() public view returns (address) { return _owner.read(); }\\n\\n    /// @dev The pending owner address\\n    AddressStorage private constant _pendingOwner = AddressStorage.wrap(keccak256(\\\"equilibria.root.UOwnable.pendingOwner\\\"));\\n    function pendingOwner() public view returns (address) { return _pendingOwner.read(); }\\n\\n    /**\\n     * @notice Initializes the contract setting `msg.sender` as the initial owner\\n     */\\n    function __UOwnable__initialize() internal onlyInitializer {\\n        _updateOwner(msg.sender);\\n    }\\n\\n    /**\\n     * @notice Updates the new pending owner\\n     * @dev Can only be called by the current owner\\n     *      New owner does not take affect until that address calls `acceptOwner()`\\n     * @param newPendingOwner New pending owner address\\n     */\\n    function updatePendingOwner(address newPendingOwner) public onlyOwner {\\n        _pendingOwner.store(newPendingOwner);\\n        emit PendingOwnerUpdated(newPendingOwner);\\n    }\\n\\n    /**\\n     * @notice Accepts and transfers the ownership of the contract to the pending owner\\n     * @dev Can only be called by the pending owner to ensure correctness\\n     */\\n    function acceptOwner() external {\\n        if (msg.sender != pendingOwner()) revert UOwnableNotPendingOwnerError(msg.sender);\\n\\n        _updateOwner(pendingOwner());\\n        updatePendingOwner(address(0));\\n    }\\n\\n    /**\\n     * @notice Updates the owner address\\n     * @param newOwner New owner address\\n     */\\n    function _updateOwner(address newOwner) private {\\n        _owner.store(newOwner);\\n        emit OwnerUpdated(newOwner);\\n    }\\n\\n    /// @dev Throws if called by any account other than the owner\\n    modifier onlyOwner() {\\n        if (owner() != msg.sender) revert UOwnableNotOwnerError(msg.sender);\\n        _;\\n    }\\n}\\n\",\"keccak256\":\"0xce2d0f77aa8d80477524b6f00524e3f8dc06053eeca8464dd766dcb5fd69ecfa\",\"license\":\"Apache-2.0\"},\"@equilibria/root/control/unstructured/UReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"./UInitializable.sol\\\";\\nimport \\\"../../storage/UStorage.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n *\\n * NOTE: This contract has been extended from the Open Zeppelin library to include an\\n *       unstructured storage pattern, so that it can be safely mixed in with upgradeable\\n *       contracts without affecting their storage patterns through inheritance.\\n */\\nabstract contract UReentrancyGuard is UInitializable {\\n    error UReentrancyGuardReentrantCallError();\\n\\n    uint256 private constant _NOT_ENTERED = 1;\\n    uint256 private constant _ENTERED = 2;\\n\\n    /**\\n     * @dev unstructured storage slot for the reentrancy status\\n     */\\n    Uint256Storage private constant _status = Uint256Storage.wrap(keccak256(\\\"equilibria.root.UReentrancyGuard.status\\\"));\\n\\n    /**\\n     * @dev Initializes the contract setting the status to _NOT_ENTERED.\\n     */\\n    function __UReentrancyGuard__initialize() internal onlyInitializer {\\n        _status.store(_NOT_ENTERED);\\n    }\\n\\n    /**\\n     * @dev Prevents a contract from calling itself, directly or indirectly.\\n     * Calling a `nonReentrant` function from another `nonReentrant`\\n     * function is not supported. It is possible to prevent this from happening\\n     * by making the `nonReentrant` function external, and make it call a\\n     * `private` function that does the actual work.\\n     */\\n    modifier nonReentrant() {\\n        // On the first call to nonReentrant, _notEntered will be true\\n        if (_status.read() == _ENTERED) revert UReentrancyGuardReentrantCallError();\\n\\n        // Any calls to nonReentrant after this point will fail\\n        _status.store(_ENTERED);\\n\\n        _;\\n\\n        // By storing the original value once again, a refund is triggered (see\\n        // https://eips.ethereum.org/EIPS/eip-2200)\\n        _status.store(_NOT_ENTERED);\\n    }\\n}\\n\",\"keccak256\":\"0x4962245ca8fdda3dc40c0f942a3568d90fb69428a6927b058018b01c90eb9fc9\",\"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/storage/UStorage.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"../number/types/UFixed18.sol\\\";\\n\\n/// @dev Stored boolean slot\\ntype BoolStorage is bytes32;\\nusing BoolStorageLib for BoolStorage global;\\n\\n/// @dev Stored uint256 slot\\ntype Uint256Storage is bytes32;\\nusing Uint256StorageLib for Uint256Storage global;\\n\\n/// @dev Stored int256 slot\\ntype Int256Storage is bytes32;\\nusing Int256StorageLib for Int256Storage global;\\n\\n/// @dev Stored address slot\\ntype AddressStorage is bytes32;\\nusing AddressStorageLib for AddressStorage global;\\n\\n/// @dev Stored bytes32 slot\\ntype Bytes32Storage is bytes32;\\nusing Bytes32StorageLib for Bytes32Storage global;\\n\\n/**\\n * @title BoolStorageLib\\n * @notice Library to manage storage and retrival of a boolean at a fixed storage slot\\n */\\nlibrary BoolStorageLib {\\n    /**\\n     * @notice Retrieves the stored value\\n     * @param self Storage slot\\n     * @return value Stored bool value\\n     */\\n    function read(BoolStorage self) internal view returns (bool value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    /**\\n     * @notice Stores the value at the specific slot\\n     * @param self Storage slot\\n     * @param value boolean value to store\\n     */\\n    function store(BoolStorage self, bool value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\\n/**\\n * @title Uint256StorageLib\\n * @notice Library to manage storage and retrival of an uint256 at a fixed storage slot\\n */\\nlibrary Uint256StorageLib {\\n    /**\\n     * @notice Retrieves the stored value\\n     * @param self Storage slot\\n     * @return value Stored uint256 value\\n     */\\n    function read(Uint256Storage self) internal view returns (uint256 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    /**\\n     * @notice Stores the value at the specific slot\\n     * @param self Storage slot\\n     * @param value uint256 value to store\\n     */\\n    function store(Uint256Storage self, uint256 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\\n/**\\n * @title Int256StorageLib\\n * @notice Library to manage storage and retrival of an int256 at a fixed storage slot\\n */\\nlibrary Int256StorageLib {\\n    /**\\n     * @notice Retrieves the stored value\\n     * @param self Storage slot\\n     * @return value Stored int256 value\\n     */\\n    function read(Int256Storage self) internal view returns (int256 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    /**\\n     * @notice Stores the value at the specific slot\\n     * @param self Storage slot\\n     * @param value int256 value to store\\n     */\\n    function store(Int256Storage self, int256 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\\n/**\\n * @title AddressStorageLib\\n * @notice Library to manage storage and retrival of an address at a fixed storage slot\\n */\\nlibrary AddressStorageLib {\\n    /**\\n     * @notice Retrieves the stored value\\n     * @param self Storage slot\\n     * @return value Stored address value\\n     */\\n    function read(AddressStorage self) internal view returns (address value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    /**\\n     * @notice Stores the value at the specific slot\\n     * @param self Storage slot\\n     * @param value address value to store\\n     */\\n    function store(AddressStorage self, address value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\\n/**\\n * @title Bytes32StorageLib\\n * @notice Library to manage storage and retrival of a bytes32 at a fixed storage slot\\n */\\nlibrary Bytes32StorageLib {\\n    /**\\n     * @notice Retrieves the stored value\\n     * @param self Storage slot\\n     * @return value Stored bytes32 value\\n     */\\n    function read(Bytes32Storage self) internal view returns (bytes32 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    /**\\n     * @notice Stores the value at the specific slot\\n     * @param self Storage slot\\n     * @param value bytes32 value to store\\n     */\\n    function store(Bytes32Storage self, bytes32 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xe2b8491d1b5aa93f7e059e1a8f156b0ab37fef9ed973be97a64f2eabfc2cc172\",\"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\"},\"@equilibria/root/token/types/Token6.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 \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"../../number/types/UFixed18.sol\\\";\\n\\n/// @dev Token6\\ntype Token6 is address;\\nusing Token6Lib for Token6 global;\\ntype Token6Storage is bytes32;\\nusing Token6StorageLib for Token6Storage global;\\n\\n/**\\n * @title Token6Lib\\n * @notice Library to manage 6-decimal ERC20s that is compliant with the fixed-decimal types.\\n * @dev Automatically converts from Base-6 token amounts to Base-18 UFixed18 amounts, with optional rounding\\n */\\nlibrary Token6Lib {\\n    using SafeERC20 for IERC20;\\n\\n    Token6 public constant ZERO = Token6.wrap(address(0));\\n\\n    uint256 private constant OFFSET = 1e12;\\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(Token6 self) internal pure returns (bool) {\\n        return Token6.unwrap(self) == Token6.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(Token6 a, Token6 b) internal pure returns (bool) {\\n        return Token6.unwrap(a) ==  Token6.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(Token6 self, address grantee) internal {\\n        IERC20(Token6.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(Token6 self, address grantee, UFixed18 amount) internal {\\n        IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, false));\\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     * @param roundUp Whether to round decimal token amount up to the next unit\\n     */\\n    function approve(Token6 self, address grantee, UFixed18 amount, bool roundUp) internal {\\n        IERC20(Token6.unwrap(self)).safeApprove(grantee, toTokenAmount(amount, roundUp));\\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(Token6 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(Token6 self, address recipient, UFixed18 amount) internal {\\n        IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, false));\\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     * @param roundUp Whether to round decimal token amount up to the next unit\\n     */\\n    function push(Token6 self, address recipient, UFixed18 amount, bool roundUp) internal {\\n        IERC20(Token6.unwrap(self)).safeTransfer(recipient, toTokenAmount(amount, roundUp));\\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(Token6 self, address benefactor, UFixed18 amount) internal {\\n        IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, false));\\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     * @param roundUp Whether to round decimal token amount up to the next unit\\n     */\\n    function pull(Token6 self, address benefactor, UFixed18 amount, bool roundUp) internal {\\n        IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, address(this), toTokenAmount(amount, roundUp));\\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(Token6 self, address benefactor, address recipient, UFixed18 amount) internal {\\n        IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, false));\\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     * @param roundUp Whether to round decimal token amount up to the next unit\\n     */\\n    function pullTo(Token6 self, address benefactor, address recipient, UFixed18 amount, bool roundUp) internal {\\n        IERC20(Token6.unwrap(self)).safeTransferFrom(benefactor, recipient, toTokenAmount(amount, roundUp));\\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(Token6 self) internal view returns (string memory) {\\n        return IERC20Metadata(Token6.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(Token6 self) internal view returns (string memory) {\\n        return IERC20Metadata(Token6.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(Token6 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(Token6 self, address account) internal view returns (UFixed18) {\\n        return fromTokenAmount(IERC20(Token6.unwrap(self)).balanceOf(account));\\n    }\\n\\n    /**\\n     * @notice Converts the unsigned fixed-decimal amount into the token amount according to\\n     *         it's defined decimals\\n     * @dev Provides the ability to \\\"round up\\\" the token amount which is useful in situations where\\n     *      are swapping one token for another and don't want to give away \\\"free\\\" units due to rounding\\n     *      errors in the favor of the user.\\n     * @param amount Amount to convert\\n     * @param roundUp Whether to round decimal token amount up to the next unit\\n     * @return Normalized token amount\\n     */\\n    function toTokenAmount(UFixed18 amount, bool roundUp) private pure returns (uint256) {\\n        return roundUp ? Math.ceilDiv(UFixed18.unwrap(amount), OFFSET) : UFixed18.unwrap(amount) / OFFSET;\\n    }\\n\\n    /**\\n     * @notice Converts the token amount into the unsigned fixed-decimal amount according to\\n     *         it's defined decimals\\n     * @param amount Token amount to convert\\n     * @return Normalized unsigned fixed-decimal amount\\n     */\\n    function fromTokenAmount(uint256 amount) private pure returns (UFixed18) {\\n        return UFixed18.wrap(amount * OFFSET);\\n    }\\n}\\n\\nlibrary Token6StorageLib {\\n    function read(Token6Storage self) internal view returns (Token6 value) {\\n        assembly {\\n            value := sload(self)\\n        }\\n    }\\n\\n    function store(Token6Storage self, Token6 value) internal {\\n        assembly {\\n            sstore(self, value)\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x5ec7bee45a0e13f91ab2399472cf11136496073ad470cd70244855e12a7b6e65\",\"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\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n    // To implement this library for multiple types with as little code\\n    // repetition as possible, we write it in terms of a generic Set type with\\n    // bytes32 values.\\n    // The Set implementation uses private functions, and user-facing\\n    // implementations (such as AddressSet) are just wrappers around the\\n    // underlying Set.\\n    // This means that we can only create new EnumerableSets for types that fit\\n    // in bytes32.\\n\\n    struct Set {\\n        // Storage of set values\\n        bytes32[] _values;\\n        // Position of the value in the `values` array, plus 1 because index 0\\n        // means a value is not in the set.\\n        mapping(bytes32 => uint256) _indexes;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function _add(Set storage set, bytes32 value) private returns (bool) {\\n        if (!_contains(set, value)) {\\n            set._values.push(value);\\n            // The value is stored at length-1, but we add 1 to all indexes\\n            // and use 0 as a sentinel value\\n            set._indexes[value] = set._values.length;\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\\n        // We read and store the value's index to prevent multiple reads from the same storage slot\\n        uint256 valueIndex = set._indexes[value];\\n\\n        if (valueIndex != 0) {\\n            // Equivalent to contains(set, value)\\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\\n            // This modifies the order of the array, as noted in {at}.\\n\\n            uint256 toDeleteIndex = valueIndex - 1;\\n            uint256 lastIndex = set._values.length - 1;\\n\\n            if (lastIndex != toDeleteIndex) {\\n                bytes32 lastValue = set._values[lastIndex];\\n\\n                // Move the last value to the index where the value to delete is\\n                set._values[toDeleteIndex] = lastValue;\\n                // Update the index for the moved value\\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\\n            }\\n\\n            // Delete the slot where the moved value was stored\\n            set._values.pop();\\n\\n            // Delete the index for the deleted slot\\n            delete set._indexes[value];\\n\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n        return set._indexes[value] != 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function _length(Set storage set) private view returns (uint256) {\\n        return set._values.length;\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n        return set._values[index];\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function _values(Set storage set) private view returns (bytes32[] memory) {\\n        return set._values;\\n    }\\n\\n    // Bytes32Set\\n\\n    struct Bytes32Set {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _add(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _remove(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n        return _contains(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(Bytes32Set storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n        return _at(set._inner, index);\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n        return _values(set._inner);\\n    }\\n\\n    // AddressSet\\n\\n    struct AddressSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(AddressSet storage set, address value) internal returns (bool) {\\n        return _add(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(AddressSet storage set, address value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(AddressSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n        return address(uint160(uint256(_at(set._inner, index))));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(AddressSet storage set) internal view returns (address[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        address[] memory result;\\n\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintSet\\n\\n    struct UintSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _add(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function length(UintSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n        return uint256(_at(set._inner, index));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        uint256[] memory result;\\n\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n}\\n\",\"keccak256\":\"0xacac2065b3ed1facff1163435890d4a6bcdc474e857e8e2c91ae5fb50418f723\",\"license\":\"MIT\"},\"contracts/controller/UControllerProvider.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@equilibria/root/control/unstructured/UInitializable.sol\\\";\\nimport \\\"@equilibria/root/storage/UStorage.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"../interfaces/IController.sol\\\";\\nimport \\\"../interfaces/IProduct.sol\\\";\\n\\n/**\\n * @title UControllerProvider\\n * @notice Mix-in that manages a controller pointer and associated permissioning modifiers.\\n * @dev Uses unstructured storage so that it is safe to mix-in to upgreadable contracts without modifying\\n *      their storage layout.\\n */\\nabstract contract UControllerProvider is UInitializable {\\n    error NotOwnerError(uint256 coordinatorId);\\n    error NotProductError(IProduct product);\\n    error NotCollateralError();\\n    error PausedError();\\n    error InvalidControllerError();\\n    error NotAccountOrMultiInvokerError(address account, address operator);\\n\\n    /// @dev The controller contract address\\n    AddressStorage private constant _controller = AddressStorage.wrap(keccak256(\\\"equilibria.perennial.UControllerProvider.controller\\\"));\\n    function controller() public view returns (IController) { return IController(_controller.read()); }\\n\\n    /**\\n     * @notice Initializes the contract state\\n     * @param controller_ Protocol Controller contract address\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function __UControllerProvider__initialize(IController controller_) internal onlyInitializer {\\n        if (!Address.isContract(address(controller_))) revert InvalidControllerError();\\n        _controller.store(address(controller_));\\n    }\\n\\n    /// @dev Only allow a valid product contract to call\\n    modifier onlyProduct {\\n        if (!controller().isProduct(IProduct(msg.sender))) revert NotProductError(IProduct(msg.sender));\\n\\n        _;\\n    }\\n\\n    /// @dev Verify that `product` is a valid product contract\\n    modifier isProduct(IProduct product) {\\n        if (!controller().isProduct(product)) revert NotProductError(product);\\n\\n        _;\\n    }\\n\\n    /// @dev Only allow the Collateral contract to call\\n    modifier onlyCollateral {\\n        if (msg.sender != address(controller().collateral())) revert NotCollateralError();\\n\\n        _;\\n    }\\n\\n    /// @dev Only allow the coordinator owner to call\\n    modifier onlyOwner(uint256 coordinatorId) {\\n        if (msg.sender != controller().owner(coordinatorId)) revert NotOwnerError(coordinatorId);\\n\\n        _;\\n    }\\n\\n    /// @dev Only allow if the protocol is currently unpaused\\n    modifier notPaused() {\\n        if (controller().paused()) revert PausedError();\\n\\n        _;\\n    }\\n\\n    /// @dev Ensure the `msg.sender` is ether the `account` or the Controller's multiInvoker\\n    modifier onlyAccountOrMultiInvoker(address account) {\\n        if (!(msg.sender == account || msg.sender == address(controller().multiInvoker()))) {\\n            revert NotAccountOrMultiInvokerError(account, msg.sender);\\n        }\\n        _;\\n    }\\n}\\n\",\"keccak256\":\"0x6758f2b7f828755e1ddfbb021b27ac0f51f6dcd2ccc8262ee2632dd465b7c19f\",\"license\":\"Apache-2.0\"},\"contracts/incentivizer/Incentivizer.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@equilibria/root/control/unstructured/UInitializable.sol\\\";\\nimport \\\"@equilibria/root/control/unstructured/UReentrancyGuard.sol\\\";\\nimport \\\"../interfaces/IIncentivizer.sol\\\";\\nimport \\\"../interfaces/IController.sol\\\";\\nimport \\\"../controller/UControllerProvider.sol\\\";\\nimport \\\"./types/ProductManager.sol\\\";\\n\\n/**\\n * @title Incentivizer\\n * @notice Manages logic and state for all incentive programs in the protocol.\\n */\\ncontract Incentivizer is IIncentivizer, UInitializable, UControllerProvider, UReentrancyGuard {\\n    /// @dev Product management state\\n    mapping(IProduct => ProductManager) private _products;\\n\\n    /// @dev Fees that have been collected, but remain unclaimed\\n    mapping(Token18 => UFixed18) public fees;\\n\\n    /**\\n     * @notice Initializes the contract state\\n     * @dev Must be called atomically as part of the upgradeable proxy deployment to\\n     *      avoid front-running\\n     * @param controller_ Factory contract address\\n     */\\n    function initialize(IController controller_) external initializer(1) {\\n        __UControllerProvider__initialize(controller_);\\n        __UReentrancyGuard__initialize();\\n    }\\n\\n    /**\\n     * @notice Creates a new incentive program\\n     * @dev Must be called as the product or protocol owner\\n     * @param product The product to create the new program on\\n     * @param programInfo Parameters for the new program\\n     * @return programId New program's ID\\n     */\\n    function create(IProduct product, ProgramInfo calldata programInfo)\\n    external\\n    nonReentrant\\n    isProduct(product)\\n    notPaused\\n    onlyOwner(programInfo.coordinatorId)\\n    returns (uint256 programId) {\\n        IController _controller = controller();\\n\\n        // Validate\\n        if (programInfo.coordinatorId != 0 && programInfo.coordinatorId != _controller.coordinatorFor(product))\\n            revert IncentivizerNotAllowedError(product);\\n        if (active(product) >= _controller.programsPerProduct())\\n            revert IncentivizerTooManyProgramsError();\\n        ProgramInfoLib.validate(programInfo);\\n\\n        // Take fee\\n        (ProgramInfo memory newProgramInfo, UFixed18 programFeeAmount) = ProgramInfoLib.deductFee(programInfo, _controller.incentivizationFee());\\n        fees[newProgramInfo.token] = fees[newProgramInfo.token].add(programFeeAmount);\\n\\n        // Register program\\n        programId = _products[product].register(newProgramInfo);\\n\\n        // Charge creator\\n        newProgramInfo.token.pull(msg.sender, programInfo.amount.sum());\\n\\n        emit ProgramCreated(\\n            product,\\n            programId,\\n            newProgramInfo,\\n            programFeeAmount\\n        );\\n    }\\n\\n    /**\\n     * @notice Completes an in-progress program early\\n     * @dev Must be called as the program owner\\n     * @param product Product that the program is running on\\n     * @param programId Program to complete early\\n     */\\n    function complete(IProduct product, uint256 programId)\\n    external\\n    nonReentrant\\n    isProgram(product, programId)\\n    notPaused\\n    onlyProgramOwner(product, programId)\\n    {\\n        ProductManagerLib.SyncResult memory syncResult = _products[product].complete(product, programId);\\n        _handleSyncResult(product, syncResult);\\n    }\\n\\n    /**\\n     * @notice Starts and completes programs as they become available\\n     * @dev Called every settle() from each product\\n     * @param currentOracleVersion The preloaded current oracle version\\n     */\\n    function sync(IOracleProvider.OracleVersion memory currentOracleVersion) external onlyProduct {\\n        IProduct product = IProduct(msg.sender);\\n\\n        ProductManagerLib.SyncResult[] memory syncResults = _products[product].sync(product, currentOracleVersion);\\n        for (uint256 i = 0; i < syncResults.length; i++) {\\n            _handleSyncResult(product, syncResults[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Handles refunding and event emitting on program start and completion\\n     * @param product Product that the program is running on\\n     * @param syncResult The data from the sync event to handle\\n     */\\n    function _handleSyncResult(IProduct product, ProductManagerLib.SyncResult memory syncResult) private {\\n        uint256 programId = syncResult.programId;\\n        if (!syncResult.refundAmount.isZero())\\n            _products[product].token(programId).push(treasury(product, programId), syncResult.refundAmount);\\n        if (syncResult.versionStarted != 0)\\n            emit ProgramStarted(product, programId, syncResult.versionStarted);\\n        if (syncResult.versionComplete != 0)\\n            emit ProgramComplete(product, programId, syncResult.versionComplete);\\n    }\\n\\n    /**\\n     * @notice Settles unsettled balance for `account`\\n     * @dev Called immediately proceeding a position update in the corresponding product\\n     * @param account Account to sync\\n     * @param currentOracleVersion The preloaded current oracle version\\n     */\\n    function syncAccount(\\n        address account,\\n        IOracleProvider.OracleVersion memory currentOracleVersion\\n    ) external onlyProduct {\\n        IProduct product = IProduct(msg.sender);\\n        _products[product].syncAccount(product, account, currentOracleVersion);\\n    }\\n\\n    /**\\n     * @notice Claims all of `msg.sender`'s rewards for `product` programs\\n     * @param product Product to claim rewards for\\n     * @param programIds Programs to claim rewards for\\n     */\\n    function claim(IProduct product, uint256[] calldata programIds)\\n    external\\n    nonReentrant\\n    {\\n        _claimProduct(msg.sender, product, programIds);\\n    }\\n\\n    /**\\n     * @notice Claims all of `account`'s rewards for `product` programs\\n     * @param account Account to claim rewards for\\n     * @param product Product to claim rewards for\\n     * @param programIds Programs to claim rewards for\\n     */\\n    function claimFor(address account, IProduct product, uint256[] calldata programIds)\\n    external\\n    nonReentrant\\n    onlyAccountOrMultiInvoker(account)\\n    {\\n        _claimProduct(account, product, programIds);\\n    }\\n\\n    /**\\n     * @notice Claims all of `msg.sender`'s rewards for a specific program\\n     * @param products Products to claim rewards for\\n     * @param programIds Programs to claim rewards for\\n     */\\n    function claim(IProduct[] calldata products, uint256[][] calldata programIds)\\n    external\\n    nonReentrant\\n    {\\n        if (products.length != programIds.length) revert IncentivizerBatchClaimArgumentMismatchError();\\n        for (uint256 i; i < products.length; i++) {\\n            _claimProduct(msg.sender, products[i], programIds[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Claims all of `msg.sender`'s rewards for `product` programs\\n     * @dev Internal helper with validation checks\\n     * @param account Account to claim rewards for\\n     * @param product Product to claim rewards for\\n     * @param programIds Programs to claim rewards for\\n     */\\n    function _claimProduct(address account, IProduct product, uint256[] memory programIds)\\n    private\\n    isProduct(product)\\n    notPaused\\n    settleForAccount(account, product)\\n    {\\n        for (uint256 i; i < programIds.length; i++) {\\n            _claimProgram(account, product, programIds[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Claims all of `msg.sender`'s rewards for `programId` on `product`\\n     * @dev Internal helper with validation checks\\n     * @param account Account to claim rewards for\\n     * @param product Product to claim rewards for\\n     * @param programId Program to claim rewards for\\n     */\\n    function _claimProgram(address account, IProduct product, uint256 programId)\\n    private\\n    isProgram(product, programId)\\n    {\\n        ProductManager storage productManager = _products[product];\\n        UFixed18 claimAmount = productManager.claim(account, programId);\\n        productManager.token(programId).push(account, claimAmount);\\n        emit Claim(product, account, programId, claimAmount);\\n    }\\n\\n    /**\\n     * @notice Claims all `tokens` fees to the protocol treasury\\n     * @param tokens Tokens to claim fees for\\n     */\\n    function claimFee(Token18[] calldata tokens) external notPaused {\\n        for(uint256 i; i < tokens.length; i++) {\\n            Token18 token = tokens[i];\\n            UFixed18 amount = fees[token];\\n\\n            fees[token] = UFixed18Lib.ZERO;\\n            token.push(controller().treasury(), amount);\\n\\n            emit FeeClaim(token, amount);\\n        }\\n    }\\n\\n    /**\\n     * @notice Returns the quantity of active programs for a given product\\n     * @param product Product to check for\\n     * @return Number of active programs\\n     */\\n    function active(IProduct product) public view returns (uint256) {\\n        return _products[product].active();\\n    }\\n\\n    /**\\n     * @notice Returns the quantity of programs for a given product\\n     * @param product Product to check for\\n     * @return Number of programs (inactive or active)\\n     */\\n    function count(IProduct product) external view returns (uint256) {\\n        return _products[product].programInfos.length;\\n    }\\n\\n    /**\\n     * @notice Returns program info for program `programId`\\n     * @param product Product to return for\\n     * @param programId Program to return for\\n     * @return Program info\\n     */\\n    function programInfos(IProduct product, uint256 programId) external view returns (ProgramInfo memory) {\\n        return _products[product].programInfos[programId];\\n    }\\n\\n    /**\\n     * @notice Returns `account`'s total unclaimed rewards for a specific program\\n     * @param product Product to return for\\n     * @param account Account to return for\\n     * @param programId Program to return for\\n     * @return `account`'s total unclaimed rewards for `programId`\\n     */\\n    function unclaimed(IProduct product, address account, uint256 programId) external view returns (UFixed18) {\\n        return _products[product].unclaimed(account, programId);\\n    }\\n\\n    /**\\n     * @notice Returns available rewards for a specific program\\n     * @param product Product to return for\\n     * @param programId Program to return for\\n     * @return Available rewards for `programId`\\n     */\\n    function available(IProduct product, uint256 programId) external view returns (UFixed18) {\\n        return _products[product].programs[programId].available;\\n    }\\n\\n    /**\\n     * @notice Returns the version started for a specific program\\n     * @param product Product to return for\\n     * @param programId Program to return for\\n     * @return The version started for `programId`\\n     */\\n    function versionStarted(IProduct product, uint256 programId) external view returns (uint256) {\\n        return _products[product].programs[programId].versionStarted;\\n    }\\n\\n    /**\\n     * @notice Returns the version completed for a specific program\\n     * @param product Product to return for\\n     * @param programId Program to return for\\n     * @return The version completed for `programId`\\n     */\\n    function versionComplete(IProduct product, uint256 programId) external view returns (uint256) {\\n        return _products[product].programs[programId].versionComplete;\\n    }\\n\\n    /**\\n     * @notice Returns the owner of a specific program\\n     * @param product Product to return for\\n     * @param programId Program to return for\\n     * @return The owner of `programId`\\n     */\\n    function owner(IProduct product, uint256 programId) public view returns (address) {\\n        return controller().owner(_products[product].programInfos[programId].coordinatorId);\\n    }\\n\\n    /**\\n     * @notice Returns the treasury of a specific program\\n     * @param product Product to return for\\n     * @param programId Program to return for\\n     * @return The treasury of `programId`\\n     */\\n    function treasury(IProduct product, uint256 programId) public view returns (address) {\\n        return controller().treasury(_products[product].programInfos[programId].coordinatorId);\\n    }\\n\\n    /// @dev Helper to fully settle an account's state\\n    modifier settleForAccount(address account, IProduct product) {\\n        product.settleAccount(account);\\n\\n        _;\\n    }\\n\\n    /// @dev Only allow the owner of `programId` to call\\n    modifier onlyProgramOwner(IProduct product, uint256 programId) {\\n        if (msg.sender != owner(product, programId)) revert IncentivizerNotProgramOwnerError(product, programId);\\n\\n        _;\\n    }\\n\\n    /// @dev Only allow a valid `programId`\\n    modifier isProgram(IProduct product, uint256 programId) {\\n        if (!_products[product].valid(programId)) revert IncentivizerInvalidProgramError(product, programId);\\n\\n        _;\\n    }\\n}\\n\",\"keccak256\":\"0x14e5aa3f60aeb5810e3a395f9ad93cb31a9559f5f0d9322f77201953d481e665\",\"license\":\"Apache-2.0\"},\"contracts/incentivizer/types/ProductManager.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport \\\"./Program.sol\\\";\\n\\n/// @dev ProductManager type\\nstruct ProductManager {\\n    /// @dev Static program state\\n    ProgramInfo[] programInfos;\\n\\n    /// @dev Dynamic program state\\n    mapping(uint256 => Program) programs;\\n\\n    /// @dev Mapping of all active programs for each product\\n    EnumerableSet.UintSet activePrograms;\\n\\n    /// @dev Mapping of all active programs for each user\\n    mapping(address => EnumerableSet.UintSet) activeProgramsFor;\\n\\n    /// @dev Mapping of the next program to watch for for each user\\n    mapping(address => uint256) nextProgramFor;\\n}\\nusing ProductManagerLib for ProductManager global;\\n\\n/**\\n * @title ProductManagerLib\\n * @notice Library that manages each product's incentivization state and logic.\\n */\\nlibrary ProductManagerLib {\\n    using EnumerableSet for EnumerableSet.UintSet;\\n\\n    /// @dev Result data for a sync event\\n    struct SyncResult {\\n        /// @dev The programId that was updated\\n        uint256 programId;\\n\\n        /// @dev If non-zero, the new versionStart value of the program\\n        uint256 versionStarted;\\n\\n        /// @dev If non-zero, the new versionComplete value of the program\\n        uint256 versionComplete;\\n\\n        /// @dev If non-zero, the amount to refund due to completion\\n        UFixed18 refundAmount;\\n    }\\n\\n    /**\\n     * @notice Registers a new program on this product\\n     * @param self The Product manager to operate on\\n     * @param programInfo The static program info\\n     * @return programId The new program's ID\\n     */\\n    function register(\\n        ProductManager storage self,\\n        ProgramInfo memory programInfo\\n    ) internal returns (uint256 programId) {\\n        programId = self.programInfos.length;\\n        self.programInfos.push(programInfo);\\n        self.programs[programId].initialize(programInfo);\\n        self.activePrograms.add(programId);\\n    }\\n\\n    /**\\n     * @notice Syncs this product with the latest data\\n     * @param self The Program manager to operate on\\n     * @param product This Product\\n     * @param currentOracleVersion The preloaded current oracle version\\n     */\\n    function sync(\\n        ProductManager storage self,\\n        IProduct product,\\n        IOracleProvider.OracleVersion memory currentOracleVersion\\n    ) internal returns (SyncResult[] memory results) {\\n\\n        uint256[] memory activeProgramIds = self.activePrograms.values();\\n        results = new SyncResult[](activeProgramIds.length);\\n\\n        for (uint256 i; i < activeProgramIds.length; i++) {\\n            // Load program\\n            uint256 programId = activeProgramIds[i];\\n            ProgramInfo memory programInfo = self.programInfos[programId];\\n            Program storage program = self.programs[programId];\\n\\n            // If timestamp-started, grab current version (first version after start)\\n            uint256 versionStarted;\\n            if (program.versionStarted == 0 && programInfo.isStarted(currentOracleVersion.timestamp)) {\\n                versionStarted = _start(self, programId, currentOracleVersion);\\n            }\\n\\n            // If timestamp-completed, grab previous version (last version before completion)\\n            uint256 versionComplete;\\n            UFixed18 refundAmount;\\n            if (program.versionComplete == 0 && programInfo.isComplete(currentOracleVersion.timestamp)) {\\n                (versionComplete, refundAmount) = _complete(self, product, programId);\\n            }\\n\\n            // Save result\\n            results[i] = SyncResult(programId, versionStarted, versionComplete, refundAmount);\\n        }\\n    }\\n\\n    /**\\n     * @notice Syncs an account for this product with the latest data\\n     * @dev Assumes that sync() has already been called as part of the transaction flow\\n     * @param self The Program manager to operate on\\n     * @param product This Product\\n     * @param account The account to sync\\n     * @param currentOracleVersion The preloaded current oracle version\\n     */\\n    function syncAccount(\\n        ProductManager storage self,\\n        IProduct product,\\n        address account,\\n        IOracleProvider.OracleVersion memory currentOracleVersion\\n    ) internal {\\n\\n        // Add any unseen programs\\n        uint256 fromProgramId = self.nextProgramFor[account];\\n        uint256 toProgramId = self.programInfos.length;\\n        for (uint256 programId = fromProgramId; programId < toProgramId; programId++) {\\n            self.activeProgramsFor[account].add(programId);\\n        }\\n        self.nextProgramFor[account] = toProgramId;\\n\\n        // Settle programs\\n        uint256[] memory activeProgramIds = self.activeProgramsFor[account].values();\\n        for (uint256 i; i < activeProgramIds.length; i++) {\\n            uint256 programId = activeProgramIds[i];\\n            Program storage program = self.programs[programId];\\n            program.settle(product, self.programInfos[programId], account, currentOracleVersion);\\n            if (!self.activePrograms.contains(programId) && currentOracleVersion.version >= program.versionComplete) {\\n                self.activeProgramsFor[account].remove(programId);\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @notice Returns the quantity of active programs for this product\\n     * @param self The Program manager to operate on\\n     * @return The quantity of active programs\\n     */\\n    function active(ProductManager storage self) internal view returns (uint256) {\\n        return self.activePrograms.length();\\n    }\\n\\n    /**\\n     * @notice Forces the specified program to complete if it hasn't already\\n     * @param self The Program manager to operate on\\n     * @param product The Product to operate on\\n     * @param programId The Program to complete\\n     * @return result The sync result data from completion\\n     */\\n    function complete(\\n        ProductManager storage self,\\n        IProduct product,\\n        uint256 programId\\n    ) internal returns (SyncResult memory result) {\\n        Program storage program = self.programs[programId];\\n\\n        // If not started, start first\\n        if (program.versionStarted == 0) {\\n            result.versionStarted = _start(self, programId, product.currentVersion());\\n        }\\n\\n        // If not completed already, complete\\n        if (program.versionComplete == 0) {\\n            (result.versionComplete, result.refundAmount) = _complete(self, product, programId);\\n        }\\n    }\\n\\n    /**\\n     * @notice Starts the program\\n     * @dev Rewards do not start accruing until the program has started\\n     *      Internal helper, does not prevent incorrectly-timed starting\\n     * @param self The Program manager to operate on\\n     * @param programId The Program to start\\n     * @param currentOracleVersion The effective starting oracle version\\n     * @return versionStarted The version that the program started\\n     */\\n    function _start(\\n        ProductManager storage self,\\n        uint256 programId,\\n        IOracleProvider.OracleVersion memory currentOracleVersion\\n    ) internal returns (uint256 versionStarted) {\\n        versionStarted = currentOracleVersion.version;\\n        self.programs[programId].start(currentOracleVersion.version);\\n    }\\n\\n    /**\\n     * @notice Completes the program\\n     * @dev Completion stops rewards from accruing\\n     *      Internal helper, does not prevent incorrectly-timed completion\\n     * @param self The Program manager to operate on\\n     * @param product The Product to operate on\\n     * @param programId The Program to complete\\n     * @return versionComplete The version that the program complete\\n     * @return refundAmount The refunded token amount\\n     */\\n    function _complete(\\n        ProductManager storage self,\\n        IProduct product,\\n        uint256 programId\\n    ) internal returns (uint256 versionComplete, UFixed18 refundAmount) {\\n        (versionComplete, refundAmount) = self.programs[programId].complete(product, self.programInfos[programId]);\\n        self.activePrograms.remove(programId);\\n    }\\n\\n    /**\\n     * @notice Claims all of `account`'s rewards for a specific program\\n     * @param self The Program manager to operate on\\n     * @param account Account to claim rewards for\\n     * @param programId Program to claim rewards for\\n     * @return Amount claimed\\n     */\\n    function claim(ProductManager storage self, address account, uint256 programId) internal returns (UFixed18) {\\n        return self.programs[programId].claim(account);\\n    }\\n\\n    /**\\n     * @notice Returns the total amount of unclaimed rewards for account `account`\\n     * @param self The Program manager to operate on\\n     * @param account The account to check for\\n     * @param programId The Program to check for\\n     * @return Total amount of unclaimed rewards for account\\n     */\\n    function unclaimed(ProductManager storage self, address account, uint256 programId) internal view returns (UFixed18) {\\n        if (!valid(self, programId)) return (UFixed18Lib.ZERO);\\n        return self.programs[programId].settled[account];\\n    }\\n\\n    /**\\n     * @notice Returns the token denominatino of the program's rewards\\n     * @param self The Program manager to operate on\\n     * @param programId The Program to check for\\n     * @return The token for the program\\n     */\\n    function token(ProductManager storage self, uint256 programId) internal view returns (Token18) {\\n        return self.programInfos[programId].token;\\n    }\\n\\n    /**\\n     * @notice Returns whether the supplied programId is valid\\n     * @param self The Program manager to operate on\\n     * @param programId The Program to check for\\n     * @return Whether the supplied programId is valid\\n     */\\n    function valid(ProductManager storage self, uint256 programId) internal view returns (bool) {\\n        return programId < self.programInfos.length;\\n    }\\n}\\n\",\"keccak256\":\"0x7db9fa9c04ec523c44d0aab52c8cd779a2b752e77bf16e0d90e4e0c159e24275\",\"license\":\"Apache-2.0\"},\"contracts/incentivizer/types/Program.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"../../interfaces/types/ProgramInfo.sol\\\";\\n\\n/// @dev Program type\\nstruct Program {\\n    /// @dev Mapping of latest rewards settled for each account\\n    mapping(address => UFixed18) settled;\\n\\n    /// @dev Total amount of rewards yet to be claimed\\n    UFixed18 available;\\n\\n    /// @dev Oracle version that the program started, 0 when hasn't started\\n    uint256 versionStarted;\\n\\n    /// @dev Oracle version that the program completed, 0 is still ongoing\\n    uint256 versionComplete;\\n}\\nusing ProgramLib for Program global;\\n\\n/**\\n * @title ProgramLib\\n * @notice Library that manages all of the mutable state for a single incentivization program.\\n */\\nlibrary ProgramLib {\\n    /**\\n     * @notice Initializes the program state\\n     * @param self The Program to operate on\\n     * @param programInfo Static program information\\n     */\\n    function initialize(Program storage self, ProgramInfo memory programInfo) internal {\\n        self.available = programInfo.amount.sum();\\n    }\\n\\n    /**\\n     * @notice Starts the program\\n     * @dev Rewards do not start accruing until the program has started accruing\\n     *      Does not stop double-starting\\n     * @param self The Program to operate on\\n     * @param oracleVersion The effective starting oracle version\\n     */\\n    function start(Program storage self, uint256 oracleVersion) internal {\\n        self.versionStarted = oracleVersion;\\n    }\\n\\n    /**\\n     * @notice Completes the program\\n     * @dev Completion stops rewards from accruing\\n     *      Does not prevent double-completion\\n     * @param self The Program to operate on\\n     * @param product The Product to operate on\\n     * @param programInfo Static program information\\n     * @return versionComplete The version that the program completed on\\n     * @return refundAmount The refund amount from the program\\n     */\\n    function complete(\\n        Program storage self,\\n        IProduct product,\\n        ProgramInfo memory programInfo\\n    ) internal returns (uint256 versionComplete, UFixed18 refundAmount) {\\n        uint256 versionStarted = self.versionStarted;\\n        versionComplete = Math.max(versionStarted, product.latestVersion());\\n        self.versionComplete = versionComplete;\\n\\n        IOracleProvider.OracleVersion memory fromOracleVersion = product.atVersion(versionStarted);\\n        IOracleProvider.OracleVersion memory toOracleVersion = product.atVersion(versionComplete);\\n\\n        uint256 inactiveDuration = programInfo.duration - (toOracleVersion.timestamp - fromOracleVersion.timestamp);\\n        refundAmount = programInfo.amount.sum().muldiv(inactiveDuration, programInfo.duration);\\n        self.available = self.available.sub(refundAmount);\\n    }\\n\\n    /**\\n     * @notice Settles unclaimed rewards for account `account`\\n     * @param self The Program to operate on\\n     * @param product The Product to operate on\\n     * @param programInfo Static program information\\n     * @param account The account to settle for\\n     * @param currentOracleVersion The preloaded current oracle version\\n     */\\n    function settle(\\n        Program storage self,\\n        IProduct product,\\n        ProgramInfo memory programInfo,\\n        address account,\\n        IOracleProvider.OracleVersion memory currentOracleVersion\\n    ) internal {\\n        UFixed18 unsettledAmount = _unsettled(self, product, programInfo, account, currentOracleVersion);\\n        self.settled[account] = self.settled[account].add(unsettledAmount);\\n        self.available = self.available.sub(unsettledAmount);\\n    }\\n\\n    /**\\n     * @notice Claims settled rewards for account `account`\\n     * @param self The Program to operate on\\n     * @param account The account to claim for\\n     */\\n    function claim(Program storage self, address account) internal returns (UFixed18 claimedAmount) {\\n        claimedAmount = self.settled[account];\\n        self.settled[account] = UFixed18Lib.ZERO;\\n    }\\n\\n    /**\\n     * @notice Returns the unsettled amount of unclaimed rewards for account `account`\\n     * @dev Clears when a program is closed\\n     *      Assumes that position is unchanged since last settlement, must be settled prior to user position update\\n     * @param self The Program to operate on\\n     * @param product The Product to operate on\\n     * @param programInfo Static program information\\n     * @param account The account to claim for\\n     * @param currentOracleVersion Current oracle version\\n     * @return amount Amount of unsettled rewards for account\\n     */\\n    function _unsettled(\\n        Program storage self,\\n        IProduct product,\\n        ProgramInfo memory programInfo,\\n        address account,\\n        IOracleProvider.OracleVersion memory currentOracleVersion\\n    ) private view returns (UFixed18 amount) {\\n        // program stage overview\\n        //\\n        // V = latest user settle version, V' = current user settle version\\n        // S = versionStarted, E = versionEnded\\n        //\\n        // (1) V   V' S           E        program not yet started\\n        // (2)   V    S     V'    E        use versionStarted -> V' for userShareDelta\\n        // (3)        S  V     V' E        use V -> V' for userShareDelta\\n        // (4)        S     V     E   V'   use V -> versionComplete for userShareDelta\\n        // (5)        S           E V   V' program already completed\\n        // (6)   V    S           E   V'   use versionStarted -> versionComplete for userShareDelta\\n        //\\n        // NOTE: V == S and V' == E both default to the inner case\\n\\n        (uint256 _versionStarted, uint256 _versionComplete) = (\\n            self.versionStarted == 0 ? currentOracleVersion.version : self.versionStarted, // start must be no earlier than current version\\n            self.versionComplete == 0 ? type(uint256).max : self.versionComplete           // we don't know when completion occurs\\n        );\\n\\n        // accruing must start between self.versionStarted and self.versionComplete\\n        uint256 fromVersion = Math.min(_versionComplete, Math.max(_versionStarted, product.latestVersion(account)));\\n        // accruing must complete between self.versionStarted and self.versionComplete, we know self.versionStarted must be no earlier than current version\\n        uint256 toVersion = Math.min(_versionComplete, currentOracleVersion.version);\\n\\n        Accumulator memory globalShareDelta = product.shareAtVersion(toVersion).sub(product.shareAtVersion(fromVersion));\\n        Accumulator memory computedUserShareDelta = product.position(account).mul(globalShareDelta);\\n        amount = UFixed18Lib.from(programInfo.amountPerShare().mul(computedUserShareDelta).sum());\\n    }\\n}\\n\",\"keccak256\":\"0xbc1acfcb2160ba7e08e515ef88bced2ef4acedba57bd55b55117fc05e4747fa5\",\"license\":\"Apache-2.0\"},\"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 receiver, IProduct product, UFixed18 amount) external;\\n    function withdrawFrom(address account, address receiver, 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\":\"0x8700bfd83bf2e8a079a0755b43be045023691546691f87064a2c3e54faad44d9\",\"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 \\\"./IMultiInvoker.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 MultiInvokerUpdated(IMultiInvoker newMultiInvoker);\\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 multiInvoker() external view returns (IMultiInvoker);\\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 updateMultiInvoker(IMultiInvoker newMultiInvoker) 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\":\"0xb6798b45b76edb91f6e56380eeeacdcfb37bbeb620a2d9c3e9993c39675bbd48\",\"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 claimFor(address account, 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\":\"0xd9d65d1190d830c8b797829f94194db86bb712e51f404e8c3e2c9b1df5645649\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IMultiInvoker.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/batcher/Batcher.sol\\\";\\n\\nimport \\\"./IController.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IMultiInvoker {\\n    /// @dev Core protocol actions that can be composed\\n    enum PerennialAction {\\n        NO_OP,\\n        DEPOSIT,\\n        WITHDRAW,\\n        OPEN_TAKE,\\n        CLOSE_TAKE,\\n        OPEN_MAKE,\\n        CLOSE_MAKE,\\n        CLAIM,\\n        WRAP,\\n        UNWRAP,\\n        WRAP_AND_DEPOSIT,\\n        WITHDRAW_AND_UNWRAP\\n    }\\n\\n    /// @dev Struct for action invocation\\n    struct Invocation {\\n        PerennialAction action;\\n        bytes args;\\n    }\\n\\n    function initialize() external;\\n    function USDC() external view returns (Token6); // solhint-disable-line func-name-mixedcase\\n    function DSU() external view returns (Token18); // solhint-disable-line func-name-mixedcase\\n    function batcher() external view returns (Batcher);\\n    function controller() external view returns (IController);\\n    function collateral() external view returns (ICollateral);\\n    function reserve() external view returns (IEmptySetReserve);\\n    function invoke(Invocation[] calldata invocations) external;\\n}\\n\",\"keccak256\":\"0xfbc93b818893aa6288297194b3750fe50da045440c08f865e09ba43e7d8a940c\",\"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\\\";\\nimport \\\"./types/PendingFeeUpdates.sol\\\";\\n\\ninterface IParamProvider {\\n    event MaintenanceUpdated(UFixed18 newMaintenance, uint256 version);\\n    event FundingFeeUpdated(UFixed18 newFundingFee, uint256 version);\\n    event MakerFeeUpdated(UFixed18 newMakerFee, uint256 version);\\n    event PendingMakerFeeUpdated(UFixed18 newMakerFee);\\n    event TakerFeeUpdated(UFixed18 newTakerFee, uint256 version);\\n    event PendingTakerFeeUpdated(UFixed18 newTakerFee);\\n    event PositionFeeUpdated(UFixed18 newPositionFee, uint256 version);\\n    event PendingPositionFeeUpdated(UFixed18 newPositionFee);\\n    event MakerLimitUpdated(UFixed18 newMakerLimit, uint256 version);\\n    event JumpRateUtilizationCurveUpdated(\\n        JumpRateUtilizationCurve,\\n        uint256 version\\n    );\\n\\n    error ParamProviderInvalidMakerFee();\\n    error ParamProviderInvalidTakerFee();\\n    error ParamProviderInvalidPositionFee();\\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 positionFee() external view returns (UFixed18);\\n    function updatePositionFee(UFixed18 newPositionFee) 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    function pendingFeeUpdates() external view returns (PendingFeeUpdates memory);\\n}\\n\",\"keccak256\":\"0x81a0a433f1e74f92945bb9d11c31ebcde049e40ecdd8195f215364067948c19f\",\"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/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 position fee share\\n        UFixed18 positionFee;\\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 openTakeFor(address account, UFixed18 amount) external;\\n    function closeTake(UFixed18 amount) external;\\n    function closeTakeFor(address account, UFixed18 amount) external;\\n    function openMake(UFixed18 amount) external;\\n    function openMakeFor(address account, UFixed18 amount) external;\\n    function closeMake(UFixed18 amount) external;\\n    function closeMakeFor(address account, 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\":\"0x989e05ee3615af1b52d4dcf506af7ceff79625f8dfad2352958590a83cb15848\",\"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 } // solhint-disable-line no-inline-assembly\\n    }\\n}\\n\",\"keccak256\":\"0x5a89942d8fe02369b25a0ae18d00cc4ad654c1657167c58cb3669d1b3b49e36b\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/types/PendingFeeUpdates.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.15;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\n/// @dev PendingFeeUpdates type. Fees can be between 0 and 1 ** 10^18, so uint64 is sufficient\\nstruct PendingFeeUpdates {\\n    bool makerFeeUpdated;\\n    uint64 pendingMakerFee;\\n    bool takerFeeUpdated;\\n    uint64 pendingTakerFee;\\n    bool positionFeeUpdated;\\n    uint64 pendingPositionFee;\\n}\\nusing PendingFeeUpdatesLib for PendingFeeUpdates global;\\ntype PendingFeeUpdatesStorage is bytes32;\\nusing PendingFeeUpdatesStorageLib for PendingFeeUpdatesStorage global;\\n\\n/**\\n * @title PendingFeeUpdatesLib\\n * @dev Library that surfaces convenience functions for the PendingFeeUpdates type\\n * @notice Library for the PendingFeeUpdates type. Allows for setting and reading fee updates and clearing state\\n */\\nlibrary PendingFeeUpdatesLib {\\n    error PendingFeeUpdatesUnsupportedValue(UFixed18 value);\\n\\n    /**\\n     * @notice Updates the pending maker fee to `newMakerFee` and sets the `makerFeeUpdated` flag\\n     * @dev Reverts if `newMakerFee` is invalid\\n     * @param self PendingFeeUpdates struct\\n     * @param newMakerFee new maker fee value\\n     */\\n    function updateMakerFee(PendingFeeUpdates memory self, UFixed18 newMakerFee) internal pure {\\n        if (UFixed18.unwrap(newMakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newMakerFee);\\n        self.pendingMakerFee = uint64(UFixed18.unwrap(newMakerFee));\\n        self.makerFeeUpdated = true;\\n    }\\n\\n    /// @dev Returns the UFixed18-wrapped pending maker fee\\n    function makerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(uint256(self.pendingMakerFee));\\n    }\\n\\n    /**\\n     * @notice Updates the pending taker fee to `newTakerFee` and sets the `takerFeeUpdated` flag\\n     * @dev Reverts if `newTakerFee` is invalid\\n     * @param self PendingFeeUpdates struct\\n     * @param newTakerFee new taker fee value\\n     */\\n    function updateTakerFee(PendingFeeUpdates memory self, UFixed18 newTakerFee) internal pure {\\n        if (UFixed18.unwrap(newTakerFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newTakerFee);\\n        self.pendingTakerFee = uint64(UFixed18.unwrap(newTakerFee));\\n        self.takerFeeUpdated = true;\\n    }\\n\\n    /// @dev Returns the UFixed18-wrapped pending taker fee\\n    function takerFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(uint256(self.pendingTakerFee));\\n    }\\n\\n    /**\\n     * @notice Updates the pending position fee to `newPositionFee` and sets the `positionFeeUpdated` flag\\n     * @dev Reverts if `newPositionFee` is invalid\\n     * @param self PendingFeeUpdates struct\\n     * @param newPositionFee new position fee value\\n     */\\n    function updatePositionFee(PendingFeeUpdates memory self, UFixed18 newPositionFee) internal pure {\\n        if (UFixed18.unwrap(newPositionFee) > type(uint64).max) revert PendingFeeUpdatesUnsupportedValue(newPositionFee);\\n        self.pendingPositionFee = uint64(UFixed18.unwrap(newPositionFee));\\n        self.positionFeeUpdated = true;\\n    }\\n\\n    /// @dev Returns the UFixed18-wrapped pending position fee\\n    function positionFee(PendingFeeUpdates memory self) internal pure returns (UFixed18) {\\n        return UFixed18.wrap(uint256(self.pendingPositionFee));\\n    }\\n\\n    /// @dev Returns true if any of the updated flags are true\\n    function hasUpdates(PendingFeeUpdates memory self) internal pure returns (bool) {\\n        return self.makerFeeUpdated || self.takerFeeUpdated || self.positionFeeUpdated;\\n    }\\n\\n    /// @dev Resets all struct values to defaults\\n    function clear(PendingFeeUpdates memory self) internal pure {\\n        self.makerFeeUpdated = false;\\n        self.pendingMakerFee = 0;\\n        self.takerFeeUpdated = false;\\n        self.pendingTakerFee = 0;\\n        self.positionFeeUpdated = false;\\n        self.pendingPositionFee = 0;\\n    }\\n}\\n\\n/**\\n * @title PendingFeeUpdatesStorageLib\\n * @notice Library that surfaces storage read and writes for the PendingFeeUpdates type\\n */\\nlibrary PendingFeeUpdatesStorageLib {\\n    struct PendingFeeUpdatesStoragePointer {\\n        PendingFeeUpdates value;\\n    }\\n\\n    function read(PendingFeeUpdatesStorage self) internal view returns (PendingFeeUpdates memory) {\\n        return _storagePointer(self).value;\\n    }\\n\\n    function store(PendingFeeUpdatesStorage self, PendingFeeUpdates memory value) internal {\\n        _storagePointer(self).value = value;\\n    }\\n\\n    function _storagePointer(\\n        PendingFeeUpdatesStorage self\\n    ) private pure returns (PendingFeeUpdatesStoragePointer storage pointer) {\\n        /// @solidity memory-safe-assembly\\n        assembly { pointer.slot := self } // solhint-disable-line no-inline-assembly\\n    }\\n}\\n\",\"keccak256\":\"0xef3eef16a3a30ec0328ebe75ccf8a12c36523c473fb81ee7c085c8164d612873\",\"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 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 pure returns (Position memory, bool) {\\n        return pre.canSettle(toOracleVersion) ? (next(self, pre), true) : (self, 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\":\"0x367918730021f3d6b7035f40c53b00b4316eb5e7fa409ed6285ba6d49971aab1\",\"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     * @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     * @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    }\\n\\n    /**\\n     * @notice Increments the maker side of the close position delta\\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    }\\n\\n    /**\\n     * @notice Increments the taker side of the open position delta\\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    }\\n\\n    /**\\n     * @notice Increments the taker side of the close position delta\\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    }\\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 latestOracleVersion The oracle version at which position was modified\\n     * @return The maker / taker fee incurred\\n     */\\n    function computeFee(\\n        PrePosition memory self,\\n        IOracleProvider.OracleVersion memory latestOracleVersion\\n    ) internal view returns (Position memory) {\\n        Position memory positionDelta = self.openPosition.add(self.closePosition);\\n\\n        (UFixed18 makerNotional, UFixed18 takerNotional) = (\\n            Fixed18Lib.from(positionDelta.maker).mul(latestOracleVersion.price).abs(),\\n            Fixed18Lib.from(positionDelta.taker).mul(latestOracleVersion.price).abs()\\n        );\\n\\n        IProduct product = IProduct(address(this));\\n        return Position(makerNotional.mul(product.makerFee()), 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\":\"0x4d4443c34648f0352ed7c26ce8b837b6c7613169e53e95d92c8c59ee9e335692\",\"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\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b50615b6180620000216000396000f3fe608060405234801561001057600080fd5b506004361061016b5760003560e01c806370f3f08b116100cd578063d758869111610081578063f77c479111610066578063f77c479114610400578063f8724aba1461041e578063faaebd211461044e5761016b565b8063d7588691146103b4578063e1e5a82e146103e45761016b565b8063a55ff01d116100b2578063a55ff01d14610360578063b774b6011461037c578063c4d66de8146103985761016b565b806370f3f08b1461031457806390672ad8146103445761016b565b80632c3e50e5116101245780634ea71327116101095780634ea713271461028457806366f8162e146102b45780636da0d540146102e45761016b565b80632c3e50e51461023857806345718278146102685761016b565b8063095c824111610155578063095c8241146101bc578063144dcdd1146101ec5780631830349c1461021c5761016b565b80628240531461017057806305d85eda1461018c575b600080fd5b61018a60048036038101906101859190614521565b61047e565b005b6101a660048036038101906101a19190614595565b6106b9565b6040516101b391906145db565b60405180910390f35b6101d660048036038101906101d19190614622565b610707565b6040516101e391906145db565b60405180910390f35b61020660048036038101906102019190614622565b610767565b6040516102139190614671565b60405180910390f35b610236600480360381019061023191906147b7565b610856565b005b610252600480360381019061024d9190614622565b610976565b60405161025f919061492d565b60405180910390f35b610282600480360381019061027d9190614948565b610a8e565b005b61029e60048036038101906102999190614595565b610ba9565b6040516102ab91906145db565b60405180910390f35b6102ce60048036038101906102c991906149a8565b610bf8565b6040516102db9190614a0a565b60405180910390f35b6102fe60048036038101906102f99190614622565b610c55565b60405161030b9190614671565b60405180910390f35b61032e60048036038101906103299190614622565b610d44565b60405161033b91906145db565b60405180910390f35b61035e60048036038101906103599190614ad1565b610da4565b005b61037a60048036038101906103759190614b52565b610f6b565b005b61039660048036038101906103919190614bd5565b6110d1565b005b6103b260048036038101906103ad9190614c60565b611349565b005b6103ce60048036038101906103c99190614cb1565b6114d8565b6040516103db91906145db565b60405180910390f35b6103fe60048036038101906103f99190614622565b611bd5565b005b610408611ec7565b6040516104159190614d12565b60405180910390f35b61043860048036038101906104339190614622565b611ef7565b6040516104459190614a0a565b60405180910390f35b61046860048036038101906104639190614d59565b611f57565b6040516104759190614a0a565b60405180910390f35b60026104a97f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b036104e0576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61051460027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b838073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806105ef5750610552611ec7565b73ffffffffffffffffffffffffffffffffffffffff1663479e58f06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c09190614dc4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6106325780336040517f6dc3a3c3000000000000000000000000000000000000000000000000000000008152600401610629929190614df1565b60405180910390fd5b61067e8585858580806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611f81565b506106b360017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b50505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805490509050919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060020154905092915050565b6000610771611ec7565b73ffffffffffffffffffffffffffffffffffffffff16634c5430a06000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000184815481106107df576107de614e1a565b5b9060005260206000209060060201600001546040518263ffffffff1660e01b815260040161080d91906145db565b602060405180830381865afa15801561082a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084e9190614e5e565b905092915050565b61085e611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192336040518263ffffffff1660e01b81526004016108969190614eac565b602060405180830381865afa1580156108b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d79190614eff565b61091857336040517f4d53256500000000000000000000000000000000000000000000000000000000815260040161090f9190614eac565b60405180910390fd5b60003390506109718184846000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121ab909392919063ffffffff16565b505050565b61097e614365565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106109d1576109d0614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b6002610ab97f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b03610af0576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b2460027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b610b703384848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611f81565b610ba460017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b505050565b6000610bf16000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124d1565b9050919050565b6000610c4c83836000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124e69092919063ffffffff16565b90509392505050565b6000610c5f611ec7565b73ffffffffffffffffffffffffffffffffffffffff1663a123c33e6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110610ccd57610ccc614e1a565b5b9060005260206000209060060201600001546040518263ffffffff1660e01b8152600401610cfb91906145db565b602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190614e5e565b905092915050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060030154905092915050565b6002610dcf7f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b03610e06576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3a60027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b818190508484905014610e79576040517f90fb223000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b84849050811015610f3057610f1d33868684818110610e9e57610e9d614e1a565b5b9050602002016020810190610eb39190614595565b858585818110610ec657610ec5614e1a565b5b9050602002810190610ed89190614f3b565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611f81565b8080610f2890614fcd565b915050610e7c565b50610f6560017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b50505050565b610f73611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192336040518263ffffffff1660e01b8152600401610fab9190614eac565b602060405180830381865afa158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190614eff565b61102d57336040517f4d5325650000000000000000000000000000000000000000000000000000000081526004016110249190614eac565b60405180910390fd5b6000339050600061108682846000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061255f9092919063ffffffff16565b905060005b81518110156110cb576110b8838383815181106110ab576110aa614e1a565b5b60200260200101516127ba565b80806110c390614fcd565b91505061108b565b50505050565b6110d9611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611123573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111479190614eff565b1561117e576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828290508110156113445760008383838181106111a1576111a0614e1a565b5b90506020020160208101906111b69190614d59565b90506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506112e161124c611ec7565b73ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190614e5e565b828473ffffffffffffffffffffffffffffffffffffffff166129219092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167f10df095d1434aed409b2f33d2a6a8456f8b0824633cc12a1b43032085aadc41d826040516113279190614a0a565b60405180910390a25050808061133c90614fcd565b915050611181565b505050565b600160008103611385576040517fb66146bd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806113af7f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b611f6f565b106113f157806040517f1e7a9d950000000000000000000000000000000000000000000000000000000081526004016113e891906145db565b60405180910390fd5b611424817f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b611f7a90919063ffffffff16565b61145860017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c61295190919063ffffffff16565b61146182612958565b611469612a3f565b61149d60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c61295190919063ffffffff16565b7fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f32816040516114cc91906145db565b60405180910390a15050565b600060026115057f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b0361153c576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157060027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b82611579611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192826040518263ffffffff1660e01b81526004016115b19190614eac565b602060405180830381865afa1580156115ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f29190614eff565b61163357806040517f4d53256500000000000000000000000000000000000000000000000000000000815260040161162a9190614eac565b60405180910390fd5b61163b611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a99190614eff565b156116e0576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600001356116ed611ec7565b73ffffffffffffffffffffffffffffffffffffffff1663a123c33e826040518263ffffffff1660e01b815260040161172591906145db565b602060405180830381865afa158015611742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117669190614e5e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117d557806040517f48f62f3c0000000000000000000000000000000000000000000000000000000081526004016117cc91906145db565b60405180910390fd5b60006117df611ec7565b9050600085600001351415801561187357508073ffffffffffffffffffffffffffffffffffffffff16637d254e66876040518263ffffffff1660e01b815260040161182a9190614eac565b602060405180830381865afa158015611847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061186b919061502a565b856000013514155b156118b557856040517fe264a5240000000000000000000000000000000000000000000000000000000081526004016118ac9190614eac565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16637d49c1b76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611900573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611924919061502a565b61192d87610ba9565b10611964576040517f1651519200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61197d85803603810190611978919061515f565b612ae7565b600080611a0887803603810190611994919061515f565b8473ffffffffffffffffffffffffffffffffffffffff16633ceda0116040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0391906151a1565b612b7e565b91509150611a628160016000856080015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612bf790919063ffffffff16565b60016000846080015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611af9826000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612c0d90919063ffffffff16565b9550611b4533611b1b89602001803603810190611b1691906151ce565b612d11565b846080015173ffffffffffffffffffffffffffffffffffffffff16612d359092919063ffffffff16565b858873ffffffffffffffffffffffffffffffffffffffff167fee8233a38e17998eb73ba822048e13762f2b68729ef94c45133866ee75754dc68484604051611b8e9291906151fb565b60405180910390a35050505050611bcf60017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b92915050565b6002611c007f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b03611c37576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c6b60027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b8181611cbd816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d6790919063ffffffff16565b611d005781816040517fd0635829000000000000000000000000000000000000000000000000000000008152600401611cf7929190615224565b60405180910390fd5b611d08611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d769190614eff565b15611dad576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383611db98282610c55565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e2a5781816040517fa17e3752000000000000000000000000000000000000000000000000000000008152600401611e21929190615224565b60405180910390fd5b6000611e7e87876000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d7b9092919063ffffffff16565b9050611e8a87826127ba565b5050505050611ec360017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b5050565b6000611ef27f0e555410d8128dff796eab5d29b97dd593ce9cab44a71b64c08244579ea60533612e5d565b905090565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060010154905092915050565b60016020528060005260406000206000915090505481565b600081549050919050565b8082555050565b81611f8a611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192826040518263ffffffff1660e01b8152600401611fc29190614eac565b602060405180830381865afa158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190614eff565b61204457806040517f4d53256500000000000000000000000000000000000000000000000000000000815260040161203b9190614eac565b60405180910390fd5b61204c611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ba9190614eff565b156120f1576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161212c9190614671565b600060405180830381600087803b15801561214657600080fd5b505af115801561215a573d6000803e3d6000fd5b5050505060005b84518110156121a25761218f878787848151811061218257612181614e1a565b5b6020026020010151612e68565b808061219a90614fcd565b915050612161565b50505050505050565b60008460050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008560000180549050905060008290505b818110156122725761225e818860040160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061300490919063ffffffff16565b50808061226a90614fcd565b915050612203565b50808660050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060006123048760040160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061301e565b905060005b81518110156124c757600082828151811061232757612326614e1a565b5b602002602001015190506000896001016000838152602001908152602001600020905061242d898b600001848154811061236457612363614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508a8a8561303f90949392919063ffffffff16565b612443828b60020161311090919063ffffffff16565b15801561245857508060030154876000015110155b156124b2576124b0828b60040160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061312a90919063ffffffff16565b505b505080806124bf90614fcd565b915050612309565b5050505050505050565b60006124df82600201613144565b9050919050565b60006124f28483612d67565b6124ff5760009050612558565b83600101600083815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b9392505050565b6060600061256f8560020161301e565b9050805167ffffffffffffffff81111561258c5761258b6146a2565b5b6040519080825280602002602001820160405280156125c557816020015b6125b26143b0565b8152602001906001900390816125aa5790505b50915060005b81518110156127b15760008282815181106125e9576125e8614e1a565b5b60200260200101519050600087600001828154811061260b5761260a614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050600088600101600084815260200190815260200160002090506000808260020154148015612703575061270288602001518461315990919063ffffffff16565b5b15612716576127138a858a61316b565b90505b60008060008460030154148015612740575061273f8a60200151866131a690919063ffffffff16565b5b15612759576127508c8c886131c7565b80925081935050505b60405180608001604052808781526020018481526020018381526020018281525089888151811061278d5761278c614e1a565b5b602002602001018190525050505050505080806127a990614fcd565b9150506125cb565b50509392505050565b6000816000015190506127d082606001516132e4565b61285c5761285b6127e18483610767565b8360600151612836846000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206132f090919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff166129219092919063ffffffff16565b5b60008260200151146128bc57808373ffffffffffffffffffffffffffffffffffffffff167f1239d8c1165187259e281474a9ae5bb87fabb197873589de0a2645ae5e2261da84602001516040516128b391906145db565b60405180910390a35b600082604001511461291c57808373ffffffffffffffffffffffffffffffffffffffff167fc590246f839a70d2279ef40b9e46b50bb20789c016f823abca87b69963f22584846040015160405161291391906145db565b60405180910390a35b505050565b61294c82828573ffffffffffffffffffffffffffffffffffffffff166133429092919063ffffffff16565b505050565b8082555050565b6129606133c8565b15801561299357506129917fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c6133d9565b155b156129ca576040517f689f12a400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129d3816133e4565b612a09576040517f14878b6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3c817f0e555410d8128dff796eab5d29b97dd593ce9cab44a71b64c08244579ea6053361340790919063ffffffff16565b50565b612a476133c8565b158015612a7a5750612a787fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c6133d9565b155b15612ab1576040517f689f12a400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ae560017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b565b612af18142613159565b15612b28576040517f0a5af16500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201518081606001511080612b4457506303c267008160600151115b15612b7b576040517f72cd3d6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b612b86614365565b600080612bba612ba785670de0b6b3a764000061340e90919063ffffffff16565b866020015161342490919063ffffffff16565b90506000612bdd612bd883886020015161347590919063ffffffff16565b612d11565b905081866020018190525085819350935050509250929050565b60008183612c05919061524d565b905092915050565b600082600001805490509050826000018290806001815401808255809150506001900390600052602060002090600602016000909190919091506000820151816000015560208201518160010160008201518160000155602082015181600101555050604082015181600301556060820151816004015560808201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050612cf4828460010160008481526020019081526020016000206134ce90919063ffffffff16565b612d0a818460020161300490919063ffffffff16565b5092915050565b6000612d2e82602001518360000151612bf790919063ffffffff16565b9050919050565b612d628230838673ffffffffffffffffffffffffffffffffffffffff166134e7909392919063ffffffff16565b505050565b600082600001805490508210905092915050565b612d836143b0565b600084600101600084815260200190815260200160002090506000816002015403612e2b57612e2185848673ffffffffffffffffffffffffffffffffffffffff16639d888e866040518163ffffffff1660e01b8152600401606060405180830381865afa158015612df8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e1c919061531c565b61316b565b8260200181815250505b6000816003015403612e5557612e428585856131c7565b8360400184606001828152508281525050505b509392505050565b600081549050919050565b8181612eba816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d6790919063ffffffff16565b612efd5781816040517fd0635829000000000000000000000000000000000000000000000000000000008152600401612ef4929190615224565b60405180910390fd5b60008060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000612f568786846135709092919063ffffffff16565b9050612f958782612f7088866132f090919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff166129219092919063ffffffff16565b848773ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e9464584604051612ff39190614a0a565b60405180910390a450505050505050565b6000613016836000018360001b6135a2565b905092915050565b6060600061302e83600001613612565b905060608190508092505050919050565b600061304e868686868661366e565b90506130a4818760000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612bf790919063ffffffff16565b8660000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061310081876001015461340e90919063ffffffff16565b8660010181905550505050505050565b6000613122836000018360001b61393e565b905092915050565b600061313c836000018360001b613961565b905092915050565b600061315282600001613a75565b9050919050565b60008260400151821015905092915050565b60008160000151905061319f8260000151856001016000868152602001908152602001600020613a8690919063ffffffff16565b9392505050565b6000826060015183604001516131bc919061524d565b821015905092915050565b6000806132bd848660000185815481106131e4576131e3614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050876001016000878152602001908152602001600020613a939092919063ffffffff16565b80925081935050506132db838660020161312a90919063ffffffff16565b50935093915050565b60008082149050919050565b600082600001828154811061330857613307614e1a565b5b906000526020600020906006020160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b6133c38363a9059cbb60e01b8484604051602401613361929190615349565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c97565b505050565b60006133d3306133e4565b15905090565b600081549050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8082555050565b6000818361341c9190615372565b905092915050565b61342c6143d8565b604051806040016040528061344e848660000151613d5e90919063ffffffff16565b815260200161346a848660200151613d5e90919063ffffffff16565b815250905092915050565b61347d6143d8565b60405180604001604052806134a38460000151866000015161340e90919063ffffffff16565b81526020016134c38460200151866020015161340e90919063ffffffff16565b815250905092915050565b6134db8160200151612d11565b82600101819055505050565b61356a846323b872dd60e01b858585604051602401613508939291906153a6565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c97565b50505050565b600061359983856001016000858152602001908152602001600020613d8790919063ffffffff16565b90509392505050565b60006135ae838361393e565b61360757826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061360c565b600090505b92915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561366257602002820191906000526020600020905b81548152602001906001019080831161364e575b50505050509050919050565b60008060008088600201541461368857876002015461368e565b83600001515b60008960030154146136a45788600301546136c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b91509150600061375882613753858b73ffffffffffffffffffffffffffffffffffffffff16638e480b208b6040518263ffffffff1660e01b815260040161370d9190614671565b602060405180830381865afa15801561372a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061374e919061502a565b613e1a565b613e34565b9050600061376a838760000151613e34565b905060006138718a73ffffffffffffffffffffffffffffffffffffffff1663476fa96d856040518263ffffffff1660e01b81526004016137aa91906145db565b6040805180830381865afa1580156137c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ea919061542d565b8b73ffffffffffffffffffffffffffffffffffffffff1663476fa96d856040518263ffffffff1660e01b815260040161382391906145db565b6040805180830381865afa15801561383f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613863919061542d565b613e4d90919063ffffffff16565b90506000613900828c73ffffffffffffffffffffffffffffffffffffffff1663b7648fb98c6040518263ffffffff1660e01b81526004016138b29190614671565b6040805180830381865afa1580156138ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f291906154aa565b613ea690919063ffffffff16565b905061392d613928613923836139158e613f0f565b613f3990919063ffffffff16565b613f92565b613fb6565b965050505050505095945050505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114613a695760006001826139939190615372565b90506000600186600001805490506139ab9190615372565b9050818114613a1a5760008660000182815481106139cc576139cb614e1a565b5b90600052602060002001549050808760000184815481106139f0576139ef614e1a565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613a2e57613a2d6154d7565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613a6f565b60009150505b92915050565b600081600001805490509050919050565b8082600201819055505050565b600080600085600201549050613b17818673ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613aee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b12919061502a565b613e1a565b925082866003018190555060008573ffffffffffffffffffffffffffffffffffffffff16637ece075d836040518263ffffffff1660e01b8152600401613b5d91906145db565b606060405180830381865afa158015613b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9e919061531c565b905060008673ffffffffffffffffffffffffffffffffffffffff16637ece075d866040518263ffffffff1660e01b8152600401613bdb91906145db565b606060405180830381865afa158015613bf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1c919061531c565b9050600082602001518260200151613c349190615372565b8760600151613c439190615372565b9050613c6a818860600151613c5b8a60200151612d11565b61400b9092919063ffffffff16565b9450613c83858a6001015461340e90919063ffffffff16565b896001018190555050505050935093915050565b6000613cf9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166140219092919063ffffffff16565b9050600081511115613d595780806020019051810190613d199190614eff565b613d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d4f90615589565b60405180910390fd5b5b505050565b6000670de0b6b3a76400008284613d7591906155a9565b613d7f9190615632565b905092915050565b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555092915050565b600081831015613e2a5781613e2c565b825b905092915050565b6000818310613e435781613e45565b825b905092915050565b613e556143f2565b6040518060400160405280613e7b8460000151866000015161403990919063ffffffff16565b8152602001613e9b8460200151866020015161403990919063ffffffff16565b815250905092915050565b613eae6143f2565b6040518060400160405280613edc8460000151613ece876000015161404f565b6140c290919063ffffffff16565b8152602001613f048460200151613ef6876020015161404f565b6140c290919063ffffffff16565b815250905092915050565b613f176143f2565b613f32826060015183602001516140eb90919063ffffffff16565b9050919050565b613f416143f2565b6040518060400160405280613f67846000015186600001516140c290919063ffffffff16565b8152602001613f87846020015186602001516140c290919063ffffffff16565b815250905092915050565b6000613faf8260200151836000015161416c90919063ffffffff16565b9050919050565b600080829050600081121561400257806040517f501f289e000000000000000000000000000000000000000000000000000000008152600401613ff99190615672565b60405180910390fd5b80915050919050565b6000614018848484614182565b90509392505050565b606061403084846000856141a4565b90509392505050565b60008183614047919061568d565b905092915050565b6000808290507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111156140b957806040517ea07eb50000000000000000000000000000000000000000000000000000000081526004016140b091906145db565b60405180910390fd5b80915050919050565b6000670de0b6b3a764000082846140d99190615721565b6140e39190615838565b905092915050565b6140f36143f2565b604051806040016040528061412d61411261410d866142b8565b61404f565b61411f876000015161404f565b6142d590919063ffffffff16565b8152602001614161614146614141866142b8565b61404f565b614153876020015161404f565b6142d590919063ffffffff16565b815250905092915050565b6000818361417a91906158a2565b905092915050565b600081838561419191906155a9565b61419b9190615632565b90509392505050565b6060824710156141e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016141e0906159a8565b60405180910390fd5b6141f2856133e4565b614231576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422890615a14565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161425a9190615aae565b60006040518083038185875af1925050503d8060008114614297576040519150601f19603f3d011682016040523d82523d6000602084013e61429c565b606091505b50915091506142ac8282866142fe565b92505050949350505050565b6000670de0b6b3a7640000826142ce91906155a9565b9050919050565b600081670de0b6b3a7640000846142ec9190615721565b6142f69190615838565b905092915050565b6060831561430e5782905061435e565b6000835111156143215782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016143559190615b09565b60405180910390fd5b9392505050565b6040518060a001604052806000815260200161437f6143d8565b81526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061444b82614420565b9050919050565b61445b81614440565b811461446657600080fd5b50565b60008135905061447881614452565b92915050565b600061448982614440565b9050919050565b6144998161447e565b81146144a457600080fd5b50565b6000813590506144b681614490565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126144e1576144e06144bc565b5b8235905067ffffffffffffffff8111156144fe576144fd6144c1565b5b60208301915083602082028301111561451a576145196144c6565b5b9250929050565b6000806000806060858703121561453b5761453a614416565b5b600061454987828801614469565b945050602061455a878288016144a7565b935050604085013567ffffffffffffffff81111561457b5761457a61441b565b5b614587878288016144cb565b925092505092959194509250565b6000602082840312156145ab576145aa614416565b5b60006145b9848285016144a7565b91505092915050565b6000819050919050565b6145d5816145c2565b82525050565b60006020820190506145f060008301846145cc565b92915050565b6145ff816145c2565b811461460a57600080fd5b50565b60008135905061461c816145f6565b92915050565b6000806040838503121561463957614638614416565b5b6000614647858286016144a7565b92505060206146588582860161460d565b9150509250929050565b61466b81614440565b82525050565b60006020820190506146866000830184614662565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6146da82614691565b810181811067ffffffffffffffff821117156146f9576146f86146a2565b5b80604052505050565b600061470c61440c565b905061471882826146d1565b919050565b6000819050919050565b6147308161471d565b811461473b57600080fd5b50565b60008135905061474d81614727565b92915050565b6000606082840312156147695761476861468c565b5b6147736060614702565b905060006147838482850161460d565b60008301525060206147978482850161460d565b60208301525060406147ab8482850161473e565b60408301525092915050565b600080608083850312156147ce576147cd614416565b5b60006147dc85828601614469565b92505060206147ed85828601614753565b9150509250929050565b614800816145c2565b82525050565b6000819050919050565b600061482b614826614821846145c2565b614806565b6145c2565b9050919050565b61483b81614810565b82525050565b6040820160008201516148576000850182614832565b50602082015161486a6020850182614832565b50505050565b600061488b61488661488184614420565b614806565b614420565b9050919050565b600061489d82614870565b9050919050565b60006148af82614892565b9050919050565b6148bf816148a4565b82525050565b60c0820160008201516148db60008501826147f7565b5060208201516148ee6020850182614841565b50604082015161490160608501826147f7565b50606082015161491460808501826147f7565b50608082015161492760a08501826148b6565b50505050565b600060c08201905061494260008301846148c5565b92915050565b60008060006040848603121561496157614960614416565b5b600061496f868287016144a7565b935050602084013567ffffffffffffffff8111156149905761498f61441b565b5b61499c868287016144cb565b92509250509250925092565b6000806000606084860312156149c1576149c0614416565b5b60006149cf868287016144a7565b93505060206149e086828701614469565b92505060406149f18682870161460d565b9150509250925092565b614a0481614810565b82525050565b6000602082019050614a1f60008301846149fb565b92915050565b60008083601f840112614a3b57614a3a6144bc565b5b8235905067ffffffffffffffff811115614a5857614a576144c1565b5b602083019150836020820283011115614a7457614a736144c6565b5b9250929050565b60008083601f840112614a9157614a906144bc565b5b8235905067ffffffffffffffff811115614aae57614aad6144c1565b5b602083019150836020820283011115614aca57614ac96144c6565b5b9250929050565b60008060008060408587031215614aeb57614aea614416565b5b600085013567ffffffffffffffff811115614b0957614b0861441b565b5b614b1587828801614a25565b9450945050602085013567ffffffffffffffff811115614b3857614b3761441b565b5b614b4487828801614a7b565b925092505092959194509250565b600060608284031215614b6857614b67614416565b5b6000614b7684828501614753565b91505092915050565b60008083601f840112614b9557614b946144bc565b5b8235905067ffffffffffffffff811115614bb257614bb16144c1565b5b602083019150836020820283011115614bce57614bcd6144c6565b5b9250929050565b60008060208385031215614bec57614beb614416565b5b600083013567ffffffffffffffff811115614c0a57614c0961441b565b5b614c1685828601614b7f565b92509250509250929050565b6000614c2d82614440565b9050919050565b614c3d81614c22565b8114614c4857600080fd5b50565b600081359050614c5a81614c34565b92915050565b600060208284031215614c7657614c75614416565b5b6000614c8484828501614c4b565b91505092915050565b600080fd5b600060c08284031215614ca857614ca7614c8d565b5b81905092915050565b60008060e08385031215614cc857614cc7614416565b5b6000614cd6858286016144a7565b9250506020614ce785828601614c92565b9150509250929050565b6000614cfc82614892565b9050919050565b614d0c81614cf1565b82525050565b6000602082019050614d276000830184614d03565b92915050565b614d3681614440565b8114614d4157600080fd5b50565b600081359050614d5381614d2d565b92915050565b600060208284031215614d6f57614d6e614416565b5b6000614d7d84828501614d44565b91505092915050565b6000614d9182614440565b9050919050565b614da181614d86565b8114614dac57600080fd5b50565b600081519050614dbe81614d98565b92915050565b600060208284031215614dda57614dd9614416565b5b6000614de884828501614daf565b91505092915050565b6000604082019050614e066000830185614662565b614e136020830184614662565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050614e5881614452565b92915050565b600060208284031215614e7457614e73614416565b5b6000614e8284828501614e49565b91505092915050565b6000614e9682614892565b9050919050565b614ea681614e8b565b82525050565b6000602082019050614ec16000830184614e9d565b92915050565b60008115159050919050565b614edc81614ec7565b8114614ee757600080fd5b50565b600081519050614ef981614ed3565b92915050565b600060208284031215614f1557614f14614416565b5b6000614f2384828501614eea565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112614f5857614f57614f2c565b5b80840192508235915067ffffffffffffffff821115614f7a57614f79614f31565b5b602083019250602082023603831315614f9657614f95614f36565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614fd8826145c2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361500a57615009614f9e565b5b600182019050919050565b600081519050615024816145f6565b92915050565b6000602082840312156150405761503f614416565b5b600061504e84828501615015565b91505092915050565b615060816145c2565b811461506b57600080fd5b50565b60008135905061507d81615057565b92915050565b6000604082840312156150995761509861468c565b5b6150a36040614702565b905060006150b38482850161506e565b60008301525060206150c78482850161506e565b60208301525092915050565b600060c082840312156150e9576150e861468c565b5b6150f360a0614702565b905060006151038482850161460d565b600083015250602061511784828501615083565b602083015250606061512b8482850161460d565b604083015250608061513f8482850161460d565b60608301525060a061515384828501614d44565b60808301525092915050565b600060c0828403121561517557615174614416565b5b6000615183848285016150d3565b91505092915050565b60008151905061519b81615057565b92915050565b6000602082840312156151b7576151b6614416565b5b60006151c58482850161518c565b91505092915050565b6000604082840312156151e4576151e3614416565b5b60006151f284828501615083565b91505092915050565b600060e08201905061521060008301856148c5565b61521d60c08301846149fb565b9392505050565b60006040820190506152396000830185614e9d565b61524660208301846145cc565b9392505050565b6000615258826145c2565b9150615263836145c2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561529857615297614f9e565b5b828201905092915050565b6000815190506152b281614727565b92915050565b6000606082840312156152ce576152cd61468c565b5b6152d86060614702565b905060006152e884828501615015565b60008301525060206152fc84828501615015565b6020830152506040615310848285016152a3565b60408301525092915050565b60006060828403121561533257615331614416565b5b6000615340848285016152b8565b91505092915050565b600060408201905061535e6000830185614662565b61536b60208301846145cc565b9392505050565b600061537d826145c2565b9150615388836145c2565b92508282101561539b5761539a614f9e565b5b828203905092915050565b60006060820190506153bb6000830186614662565b6153c86020830185614662565b6153d560408301846145cc565b949350505050565b6000604082840312156153f3576153f261468c565b5b6153fd6040614702565b9050600061540d848285016152a3565b6000830152506020615421848285016152a3565b60208301525092915050565b60006040828403121561544357615442614416565b5b6000615451848285016153dd565b91505092915050565b6000604082840312156154705761546f61468c565b5b61547a6040614702565b9050600061548a8482850161518c565b600083015250602061549e8482850161518c565b60208301525092915050565b6000604082840312156154c0576154bf614416565b5b60006154ce8482850161545a565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082825260208201905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615573602a83615506565b915061557e82615517565b604082019050919050565b600060208201905081810360008301526155a281615566565b9050919050565b60006155b4826145c2565b91506155bf836145c2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155f8576155f7614f9e565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061563d826145c2565b9150615648836145c2565b92508261565857615657615603565b5b828204905092915050565b61566c8161471d565b82525050565b60006020820190506156876000830184615663565b92915050565b60006156988261471d565b91506156a38361471d565b9250827f8000000000000000000000000000000000000000000000000000000000000000018212600084121516156156de576156dd614f9e565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01821360008412161561571657615715614f9e565b5b828203905092915050565b600061572c8261471d565b91506157378361471d565b9250827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211600084136000841316161561577657615775614f9e565b5b817f800000000000000000000000000000000000000000000000000000000000000005831260008412600084131616156157b3576157b2614f9e565b5b827f800000000000000000000000000000000000000000000000000000000000000005821260008413600084121616156157f0576157ef614f9e565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff058212600084126000841216161561582d5761582c614f9e565b5b828202905092915050565b60006158438261471d565b915061584e8361471d565b92508261585e5761585d615603565b5b600160000383147f80000000000000000000000000000000000000000000000000000000000000008314161561589757615896614f9e565b5b828205905092915050565b60006158ad8261471d565b91506158b88361471d565b9250817f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038313600083121516156158f3576158f2614f9e565b5b817f800000000000000000000000000000000000000000000000000000000000000003831260008312161561592b5761592a614f9e565b5b828201905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000615992602683615506565b915061599d82615936565b604082019050919050565b600060208201905081810360008301526159c181615985565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006159fe601d83615506565b9150615a09826159c8565b602082019050919050565b60006020820190508181036000830152615a2d816159f1565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a68578082015181840152602081019050615a4d565b83811115615a77576000848401525b50505050565b6000615a8882615a34565b615a928185615a3f565b9350615aa2818560208601615a4a565b80840191505092915050565b6000615aba8284615a7d565b915081905092915050565b600081519050919050565b6000615adb82615ac5565b615ae58185615506565b9350615af5818560208601615a4a565b615afe81614691565b840191505092915050565b60006020820190508181036000830152615b238184615ad0565b90509291505056fea264697066735822122082e9e91072630c6aecaf2986f53f9f659c308576ffcec20b0a3728c7613a1bcd64736f6c634300080f0033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061016b5760003560e01c806370f3f08b116100cd578063d758869111610081578063f77c479111610066578063f77c479114610400578063f8724aba1461041e578063faaebd211461044e5761016b565b8063d7588691146103b4578063e1e5a82e146103e45761016b565b8063a55ff01d116100b2578063a55ff01d14610360578063b774b6011461037c578063c4d66de8146103985761016b565b806370f3f08b1461031457806390672ad8146103445761016b565b80632c3e50e5116101245780634ea71327116101095780634ea713271461028457806366f8162e146102b45780636da0d540146102e45761016b565b80632c3e50e51461023857806345718278146102685761016b565b8063095c824111610155578063095c8241146101bc578063144dcdd1146101ec5780631830349c1461021c5761016b565b80628240531461017057806305d85eda1461018c575b600080fd5b61018a60048036038101906101859190614521565b61047e565b005b6101a660048036038101906101a19190614595565b6106b9565b6040516101b391906145db565b60405180910390f35b6101d660048036038101906101d19190614622565b610707565b6040516101e391906145db565b60405180910390f35b61020660048036038101906102019190614622565b610767565b6040516102139190614671565b60405180910390f35b610236600480360381019061023191906147b7565b610856565b005b610252600480360381019061024d9190614622565b610976565b60405161025f919061492d565b60405180910390f35b610282600480360381019061027d9190614948565b610a8e565b005b61029e60048036038101906102999190614595565b610ba9565b6040516102ab91906145db565b60405180910390f35b6102ce60048036038101906102c991906149a8565b610bf8565b6040516102db9190614a0a565b60405180910390f35b6102fe60048036038101906102f99190614622565b610c55565b60405161030b9190614671565b60405180910390f35b61032e60048036038101906103299190614622565b610d44565b60405161033b91906145db565b60405180910390f35b61035e60048036038101906103599190614ad1565b610da4565b005b61037a60048036038101906103759190614b52565b610f6b565b005b61039660048036038101906103919190614bd5565b6110d1565b005b6103b260048036038101906103ad9190614c60565b611349565b005b6103ce60048036038101906103c99190614cb1565b6114d8565b6040516103db91906145db565b60405180910390f35b6103fe60048036038101906103f99190614622565b611bd5565b005b610408611ec7565b6040516104159190614d12565b60405180910390f35b61043860048036038101906104339190614622565b611ef7565b6040516104459190614a0a565b60405180910390f35b61046860048036038101906104639190614d59565b611f57565b6040516104759190614a0a565b60405180910390f35b60026104a97f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b036104e0576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61051460027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b838073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806105ef5750610552611ec7565b73ffffffffffffffffffffffffffffffffffffffff1663479e58f06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c09190614dc4565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6106325780336040517f6dc3a3c3000000000000000000000000000000000000000000000000000000008152600401610629929190614df1565b60405180910390fd5b61067e8585858580806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611f81565b506106b360017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b50505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805490509050919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060020154905092915050565b6000610771611ec7565b73ffffffffffffffffffffffffffffffffffffffff16634c5430a06000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000184815481106107df576107de614e1a565b5b9060005260206000209060060201600001546040518263ffffffff1660e01b815260040161080d91906145db565b602060405180830381865afa15801561082a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084e9190614e5e565b905092915050565b61085e611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192336040518263ffffffff1660e01b81526004016108969190614eac565b602060405180830381865afa1580156108b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d79190614eff565b61091857336040517f4d53256500000000000000000000000000000000000000000000000000000000815260040161090f9190614eac565b60405180910390fd5b60003390506109718184846000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121ab909392919063ffffffff16565b505050565b61097e614365565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000182815481106109d1576109d0614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b6002610ab97f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b03610af0576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b2460027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b610b703384848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611f81565b610ba460017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b505050565b6000610bf16000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124d1565b9050919050565b6000610c4c83836000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124e69092919063ffffffff16565b90509392505050565b6000610c5f611ec7565b73ffffffffffffffffffffffffffffffffffffffff1663a123c33e6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110610ccd57610ccc614e1a565b5b9060005260206000209060060201600001546040518263ffffffff1660e01b8152600401610cfb91906145db565b602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190614e5e565b905092915050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060030154905092915050565b6002610dcf7f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b03610e06576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3a60027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b818190508484905014610e79576040517f90fb223000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b84849050811015610f3057610f1d33868684818110610e9e57610e9d614e1a565b5b9050602002016020810190610eb39190614595565b858585818110610ec657610ec5614e1a565b5b9050602002810190610ed89190614f3b565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050611f81565b8080610f2890614fcd565b915050610e7c565b50610f6560017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b50505050565b610f73611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192336040518263ffffffff1660e01b8152600401610fab9190614eac565b602060405180830381865afa158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec9190614eff565b61102d57336040517f4d5325650000000000000000000000000000000000000000000000000000000081526004016110249190614eac565b60405180910390fd5b6000339050600061108682846000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061255f9092919063ffffffff16565b905060005b81518110156110cb576110b8838383815181106110ab576110aa614e1a565b5b60200260200101516127ba565b80806110c390614fcd565b91505061108b565b50505050565b6110d9611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611123573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111479190614eff565b1561117e576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b828290508110156113445760008383838181106111a1576111a0614e1a565b5b90506020020160208101906111b69190614d59565b90506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506112e161124c611ec7565b73ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190614e5e565b828473ffffffffffffffffffffffffffffffffffffffff166129219092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167f10df095d1434aed409b2f33d2a6a8456f8b0824633cc12a1b43032085aadc41d826040516113279190614a0a565b60405180910390a25050808061133c90614fcd565b915050611181565b505050565b600160008103611385576040517fb66146bd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806113af7f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b611f6f565b106113f157806040517f1e7a9d950000000000000000000000000000000000000000000000000000000081526004016113e891906145db565b60405180910390fd5b611424817f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b611f7a90919063ffffffff16565b61145860017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c61295190919063ffffffff16565b61146182612958565b611469612a3f565b61149d60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c61295190919063ffffffff16565b7fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f32816040516114cc91906145db565b60405180910390a15050565b600060026115057f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b0361153c576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157060027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b82611579611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192826040518263ffffffff1660e01b81526004016115b19190614eac565b602060405180830381865afa1580156115ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f29190614eff565b61163357806040517f4d53256500000000000000000000000000000000000000000000000000000000815260040161162a9190614eac565b60405180910390fd5b61163b611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a99190614eff565b156116e0576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600001356116ed611ec7565b73ffffffffffffffffffffffffffffffffffffffff1663a123c33e826040518263ffffffff1660e01b815260040161172591906145db565b602060405180830381865afa158015611742573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117669190614e5e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117d557806040517f48f62f3c0000000000000000000000000000000000000000000000000000000081526004016117cc91906145db565b60405180910390fd5b60006117df611ec7565b9050600085600001351415801561187357508073ffffffffffffffffffffffffffffffffffffffff16637d254e66876040518263ffffffff1660e01b815260040161182a9190614eac565b602060405180830381865afa158015611847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061186b919061502a565b856000013514155b156118b557856040517fe264a5240000000000000000000000000000000000000000000000000000000081526004016118ac9190614eac565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16637d49c1b76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611900573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611924919061502a565b61192d87610ba9565b10611964576040517f1651519200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61197d85803603810190611978919061515f565b612ae7565b600080611a0887803603810190611994919061515f565b8473ffffffffffffffffffffffffffffffffffffffff16633ceda0116040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0391906151a1565b612b7e565b91509150611a628160016000856080015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612bf790919063ffffffff16565b60016000846080015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611af9826000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612c0d90919063ffffffff16565b9550611b4533611b1b89602001803603810190611b1691906151ce565b612d11565b846080015173ffffffffffffffffffffffffffffffffffffffff16612d359092919063ffffffff16565b858873ffffffffffffffffffffffffffffffffffffffff167fee8233a38e17998eb73ba822048e13762f2b68729ef94c45133866ee75754dc68484604051611b8e9291906151fb565b60405180910390a35050505050611bcf60017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b92915050565b6002611c007f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f6f565b03611c37576040517ff320323600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c6b60027f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b8181611cbd816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d6790919063ffffffff16565b611d005781816040517fd0635829000000000000000000000000000000000000000000000000000000008152600401611cf7929190615224565b60405180910390fd5b611d08611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d769190614eff565b15611dad576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383611db98282610c55565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e2a5781816040517fa17e3752000000000000000000000000000000000000000000000000000000008152600401611e21929190615224565b60405180910390fd5b6000611e7e87876000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d7b9092919063ffffffff16565b9050611e8a87826127ba565b5050505050611ec360017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b5050565b6000611ef27f0e555410d8128dff796eab5d29b97dd593ce9cab44a71b64c08244579ea60533612e5d565b905090565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600083815260200190815260200160002060010154905092915050565b60016020528060005260406000206000915090505481565b600081549050919050565b8082555050565b81611f8a611ec7565b73ffffffffffffffffffffffffffffffffffffffff16637fd29192826040518263ffffffff1660e01b8152600401611fc29190614eac565b602060405180830381865afa158015611fdf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120039190614eff565b61204457806040517f4d53256500000000000000000000000000000000000000000000000000000000815260040161203b9190614eac565b60405180910390fd5b61204c611ec7565b73ffffffffffffffffffffffffffffffffffffffff16635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ba9190614eff565b156120f1576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83838073ffffffffffffffffffffffffffffffffffffffff1663f667f897836040518263ffffffff1660e01b815260040161212c9190614671565b600060405180830381600087803b15801561214657600080fd5b505af115801561215a573d6000803e3d6000fd5b5050505060005b84518110156121a25761218f878787848151811061218257612181614e1a565b5b6020026020010151612e68565b808061219a90614fcd565b915050612161565b50505050505050565b60008460050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008560000180549050905060008290505b818110156122725761225e818860040160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061300490919063ffffffff16565b50808061226a90614fcd565b915050612203565b50808660050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060006123048760040160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061301e565b905060005b81518110156124c757600082828151811061232757612326614e1a565b5b602002602001015190506000896001016000838152602001908152602001600020905061242d898b600001848154811061236457612363614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508a8a8561303f90949392919063ffffffff16565b612443828b60020161311090919063ffffffff16565b15801561245857508060030154876000015110155b156124b2576124b0828b60040160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061312a90919063ffffffff16565b505b505080806124bf90614fcd565b915050612309565b5050505050505050565b60006124df82600201613144565b9050919050565b60006124f28483612d67565b6124ff5760009050612558565b83600101600083815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b9392505050565b6060600061256f8560020161301e565b9050805167ffffffffffffffff81111561258c5761258b6146a2565b5b6040519080825280602002602001820160405280156125c557816020015b6125b26143b0565b8152602001906001900390816125aa5790505b50915060005b81518110156127b15760008282815181106125e9576125e8614e1a565b5b60200260200101519050600087600001828154811061260b5761260a614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050600088600101600084815260200190815260200160002090506000808260020154148015612703575061270288602001518461315990919063ffffffff16565b5b15612716576127138a858a61316b565b90505b60008060008460030154148015612740575061273f8a60200151866131a690919063ffffffff16565b5b15612759576127508c8c886131c7565b80925081935050505b60405180608001604052808781526020018481526020018381526020018281525089888151811061278d5761278c614e1a565b5b602002602001018190525050505050505080806127a990614fcd565b9150506125cb565b50509392505050565b6000816000015190506127d082606001516132e4565b61285c5761285b6127e18483610767565b8360600151612836846000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206132f090919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff166129219092919063ffffffff16565b5b60008260200151146128bc57808373ffffffffffffffffffffffffffffffffffffffff167f1239d8c1165187259e281474a9ae5bb87fabb197873589de0a2645ae5e2261da84602001516040516128b391906145db565b60405180910390a35b600082604001511461291c57808373ffffffffffffffffffffffffffffffffffffffff167fc590246f839a70d2279ef40b9e46b50bb20789c016f823abca87b69963f22584846040015160405161291391906145db565b60405180910390a35b505050565b61294c82828573ffffffffffffffffffffffffffffffffffffffff166133429092919063ffffffff16565b505050565b8082555050565b6129606133c8565b15801561299357506129917fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c6133d9565b155b156129ca576040517f689f12a400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129d3816133e4565b612a09576040517f14878b6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a3c817f0e555410d8128dff796eab5d29b97dd593ce9cab44a71b64c08244579ea6053361340790919063ffffffff16565b50565b612a476133c8565b158015612a7a5750612a787fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c6133d9565b155b15612ab1576040517f689f12a400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ae560017f1b30fe15febd596dffd21d4da0657732eea42b4b5a9789e3e6daab3d570999d7611f7a90919063ffffffff16565b565b612af18142613159565b15612b28576040517f0a5af16500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6201518081606001511080612b4457506303c267008160600151115b15612b7b576040517f72cd3d6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b612b86614365565b600080612bba612ba785670de0b6b3a764000061340e90919063ffffffff16565b866020015161342490919063ffffffff16565b90506000612bdd612bd883886020015161347590919063ffffffff16565b612d11565b905081866020018190525085819350935050509250929050565b60008183612c05919061524d565b905092915050565b600082600001805490509050826000018290806001815401808255809150506001900390600052602060002090600602016000909190919091506000820151816000015560208201518160010160008201518160000155602082015181600101555050604082015181600301556060820151816004015560808201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050612cf4828460010160008481526020019081526020016000206134ce90919063ffffffff16565b612d0a818460020161300490919063ffffffff16565b5092915050565b6000612d2e82602001518360000151612bf790919063ffffffff16565b9050919050565b612d628230838673ffffffffffffffffffffffffffffffffffffffff166134e7909392919063ffffffff16565b505050565b600082600001805490508210905092915050565b612d836143b0565b600084600101600084815260200190815260200160002090506000816002015403612e2b57612e2185848673ffffffffffffffffffffffffffffffffffffffff16639d888e866040518163ffffffff1660e01b8152600401606060405180830381865afa158015612df8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e1c919061531c565b61316b565b8260200181815250505b6000816003015403612e5557612e428585856131c7565b8360400184606001828152508281525050505b509392505050565b600081549050919050565b8181612eba816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d6790919063ffffffff16565b612efd5781816040517fd0635829000000000000000000000000000000000000000000000000000000008152600401612ef4929190615224565b60405180910390fd5b60008060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000612f568786846135709092919063ffffffff16565b9050612f958782612f7088866132f090919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff166129219092919063ffffffff16565b848773ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e9464584604051612ff39190614a0a565b60405180910390a450505050505050565b6000613016836000018360001b6135a2565b905092915050565b6060600061302e83600001613612565b905060608190508092505050919050565b600061304e868686868661366e565b90506130a4818760000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612bf790919063ffffffff16565b8660000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061310081876001015461340e90919063ffffffff16565b8660010181905550505050505050565b6000613122836000018360001b61393e565b905092915050565b600061313c836000018360001b613961565b905092915050565b600061315282600001613a75565b9050919050565b60008260400151821015905092915050565b60008160000151905061319f8260000151856001016000868152602001908152602001600020613a8690919063ffffffff16565b9392505050565b6000826060015183604001516131bc919061524d565b821015905092915050565b6000806132bd848660000185815481106131e4576131e3614e1a565b5b90600052602060002090600602016040518060a0016040529081600082015481526020016001820160405180604001604052908160008201548152602001600182015481525050815260200160038201548152602001600482015481526020016005820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050876001016000878152602001908152602001600020613a939092919063ffffffff16565b80925081935050506132db838660020161312a90919063ffffffff16565b50935093915050565b60008082149050919050565b600082600001828154811061330857613307614e1a565b5b906000526020600020906006020160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b6133c38363a9059cbb60e01b8484604051602401613361929190615349565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c97565b505050565b60006133d3306133e4565b15905090565b600081549050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b8082555050565b6000818361341c9190615372565b905092915050565b61342c6143d8565b604051806040016040528061344e848660000151613d5e90919063ffffffff16565b815260200161346a848660200151613d5e90919063ffffffff16565b815250905092915050565b61347d6143d8565b60405180604001604052806134a38460000151866000015161340e90919063ffffffff16565b81526020016134c38460200151866020015161340e90919063ffffffff16565b815250905092915050565b6134db8160200151612d11565b82600101819055505050565b61356a846323b872dd60e01b858585604051602401613508939291906153a6565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c97565b50505050565b600061359983856001016000858152602001908152602001600020613d8790919063ffffffff16565b90509392505050565b60006135ae838361393e565b61360757826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061360c565b600090505b92915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561366257602002820191906000526020600020905b81548152602001906001019080831161364e575b50505050509050919050565b60008060008088600201541461368857876002015461368e565b83600001515b60008960030154146136a45788600301546136c6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b91509150600061375882613753858b73ffffffffffffffffffffffffffffffffffffffff16638e480b208b6040518263ffffffff1660e01b815260040161370d9190614671565b602060405180830381865afa15801561372a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061374e919061502a565b613e1a565b613e34565b9050600061376a838760000151613e34565b905060006138718a73ffffffffffffffffffffffffffffffffffffffff1663476fa96d856040518263ffffffff1660e01b81526004016137aa91906145db565b6040805180830381865afa1580156137c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137ea919061542d565b8b73ffffffffffffffffffffffffffffffffffffffff1663476fa96d856040518263ffffffff1660e01b815260040161382391906145db565b6040805180830381865afa15801561383f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613863919061542d565b613e4d90919063ffffffff16565b90506000613900828c73ffffffffffffffffffffffffffffffffffffffff1663b7648fb98c6040518263ffffffff1660e01b81526004016138b29190614671565b6040805180830381865afa1580156138ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f291906154aa565b613ea690919063ffffffff16565b905061392d613928613923836139158e613f0f565b613f3990919063ffffffff16565b613f92565b613fb6565b965050505050505095945050505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114613a695760006001826139939190615372565b90506000600186600001805490506139ab9190615372565b9050818114613a1a5760008660000182815481106139cc576139cb614e1a565b5b90600052602060002001549050808760000184815481106139f0576139ef614e1a565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613a2e57613a2d6154d7565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613a6f565b60009150505b92915050565b600081600001805490509050919050565b8082600201819055505050565b600080600085600201549050613b17818673ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613aee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b12919061502a565b613e1a565b925082866003018190555060008573ffffffffffffffffffffffffffffffffffffffff16637ece075d836040518263ffffffff1660e01b8152600401613b5d91906145db565b606060405180830381865afa158015613b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9e919061531c565b905060008673ffffffffffffffffffffffffffffffffffffffff16637ece075d866040518263ffffffff1660e01b8152600401613bdb91906145db565b606060405180830381865afa158015613bf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1c919061531c565b9050600082602001518260200151613c349190615372565b8760600151613c439190615372565b9050613c6a818860600151613c5b8a60200151612d11565b61400b9092919063ffffffff16565b9450613c83858a6001015461340e90919063ffffffff16565b896001018190555050505050935093915050565b6000613cf9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166140219092919063ffffffff16565b9050600081511115613d595780806020019051810190613d199190614eff565b613d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d4f90615589565b60405180910390fd5b5b505050565b6000670de0b6b3a76400008284613d7591906155a9565b613d7f9190615632565b905092915050565b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008360000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555092915050565b600081831015613e2a5781613e2c565b825b905092915050565b6000818310613e435781613e45565b825b905092915050565b613e556143f2565b6040518060400160405280613e7b8460000151866000015161403990919063ffffffff16565b8152602001613e9b8460200151866020015161403990919063ffffffff16565b815250905092915050565b613eae6143f2565b6040518060400160405280613edc8460000151613ece876000015161404f565b6140c290919063ffffffff16565b8152602001613f048460200151613ef6876020015161404f565b6140c290919063ffffffff16565b815250905092915050565b613f176143f2565b613f32826060015183602001516140eb90919063ffffffff16565b9050919050565b613f416143f2565b6040518060400160405280613f67846000015186600001516140c290919063ffffffff16565b8152602001613f87846020015186602001516140c290919063ffffffff16565b815250905092915050565b6000613faf8260200151836000015161416c90919063ffffffff16565b9050919050565b600080829050600081121561400257806040517f501f289e000000000000000000000000000000000000000000000000000000008152600401613ff99190615672565b60405180910390fd5b80915050919050565b6000614018848484614182565b90509392505050565b606061403084846000856141a4565b90509392505050565b60008183614047919061568d565b905092915050565b6000808290507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111156140b957806040517ea07eb50000000000000000000000000000000000000000000000000000000081526004016140b091906145db565b60405180910390fd5b80915050919050565b6000670de0b6b3a764000082846140d99190615721565b6140e39190615838565b905092915050565b6140f36143f2565b604051806040016040528061412d61411261410d866142b8565b61404f565b61411f876000015161404f565b6142d590919063ffffffff16565b8152602001614161614146614141866142b8565b61404f565b614153876020015161404f565b6142d590919063ffffffff16565b815250905092915050565b6000818361417a91906158a2565b905092915050565b600081838561419191906155a9565b61419b9190615632565b90509392505050565b6060824710156141e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016141e0906159a8565b60405180910390fd5b6141f2856133e4565b614231576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161422890615a14565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161425a9190615aae565b60006040518083038185875af1925050503d8060008114614297576040519150601f19603f3d011682016040523d82523d6000602084013e61429c565b606091505b50915091506142ac8282866142fe565b92505050949350505050565b6000670de0b6b3a7640000826142ce91906155a9565b9050919050565b600081670de0b6b3a7640000846142ec9190615721565b6142f69190615838565b905092915050565b6060831561430e5782905061435e565b6000835111156143215782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016143559190615b09565b60405180910390fd5b9392505050565b6040518060a001604052806000815260200161437f6143d8565b81526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061444b82614420565b9050919050565b61445b81614440565b811461446657600080fd5b50565b60008135905061447881614452565b92915050565b600061448982614440565b9050919050565b6144998161447e565b81146144a457600080fd5b50565b6000813590506144b681614490565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126144e1576144e06144bc565b5b8235905067ffffffffffffffff8111156144fe576144fd6144c1565b5b60208301915083602082028301111561451a576145196144c6565b5b9250929050565b6000806000806060858703121561453b5761453a614416565b5b600061454987828801614469565b945050602061455a878288016144a7565b935050604085013567ffffffffffffffff81111561457b5761457a61441b565b5b614587878288016144cb565b925092505092959194509250565b6000602082840312156145ab576145aa614416565b5b60006145b9848285016144a7565b91505092915050565b6000819050919050565b6145d5816145c2565b82525050565b60006020820190506145f060008301846145cc565b92915050565b6145ff816145c2565b811461460a57600080fd5b50565b60008135905061461c816145f6565b92915050565b6000806040838503121561463957614638614416565b5b6000614647858286016144a7565b92505060206146588582860161460d565b9150509250929050565b61466b81614440565b82525050565b60006020820190506146866000830184614662565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6146da82614691565b810181811067ffffffffffffffff821117156146f9576146f86146a2565b5b80604052505050565b600061470c61440c565b905061471882826146d1565b919050565b6000819050919050565b6147308161471d565b811461473b57600080fd5b50565b60008135905061474d81614727565b92915050565b6000606082840312156147695761476861468c565b5b6147736060614702565b905060006147838482850161460d565b60008301525060206147978482850161460d565b60208301525060406147ab8482850161473e565b60408301525092915050565b600080608083850312156147ce576147cd614416565b5b60006147dc85828601614469565b92505060206147ed85828601614753565b9150509250929050565b614800816145c2565b82525050565b6000819050919050565b600061482b614826614821846145c2565b614806565b6145c2565b9050919050565b61483b81614810565b82525050565b6040820160008201516148576000850182614832565b50602082015161486a6020850182614832565b50505050565b600061488b61488661488184614420565b614806565b614420565b9050919050565b600061489d82614870565b9050919050565b60006148af82614892565b9050919050565b6148bf816148a4565b82525050565b60c0820160008201516148db60008501826147f7565b5060208201516148ee6020850182614841565b50604082015161490160608501826147f7565b50606082015161491460808501826147f7565b50608082015161492760a08501826148b6565b50505050565b600060c08201905061494260008301846148c5565b92915050565b60008060006040848603121561496157614960614416565b5b600061496f868287016144a7565b935050602084013567ffffffffffffffff8111156149905761498f61441b565b5b61499c868287016144cb565b92509250509250925092565b6000806000606084860312156149c1576149c0614416565b5b60006149cf868287016144a7565b93505060206149e086828701614469565b92505060406149f18682870161460d565b9150509250925092565b614a0481614810565b82525050565b6000602082019050614a1f60008301846149fb565b92915050565b60008083601f840112614a3b57614a3a6144bc565b5b8235905067ffffffffffffffff811115614a5857614a576144c1565b5b602083019150836020820283011115614a7457614a736144c6565b5b9250929050565b60008083601f840112614a9157614a906144bc565b5b8235905067ffffffffffffffff811115614aae57614aad6144c1565b5b602083019150836020820283011115614aca57614ac96144c6565b5b9250929050565b60008060008060408587031215614aeb57614aea614416565b5b600085013567ffffffffffffffff811115614b0957614b0861441b565b5b614b1587828801614a25565b9450945050602085013567ffffffffffffffff811115614b3857614b3761441b565b5b614b4487828801614a7b565b925092505092959194509250565b600060608284031215614b6857614b67614416565b5b6000614b7684828501614753565b91505092915050565b60008083601f840112614b9557614b946144bc565b5b8235905067ffffffffffffffff811115614bb257614bb16144c1565b5b602083019150836020820283011115614bce57614bcd6144c6565b5b9250929050565b60008060208385031215614bec57614beb614416565b5b600083013567ffffffffffffffff811115614c0a57614c0961441b565b5b614c1685828601614b7f565b92509250509250929050565b6000614c2d82614440565b9050919050565b614c3d81614c22565b8114614c4857600080fd5b50565b600081359050614c5a81614c34565b92915050565b600060208284031215614c7657614c75614416565b5b6000614c8484828501614c4b565b91505092915050565b600080fd5b600060c08284031215614ca857614ca7614c8d565b5b81905092915050565b60008060e08385031215614cc857614cc7614416565b5b6000614cd6858286016144a7565b9250506020614ce785828601614c92565b9150509250929050565b6000614cfc82614892565b9050919050565b614d0c81614cf1565b82525050565b6000602082019050614d276000830184614d03565b92915050565b614d3681614440565b8114614d4157600080fd5b50565b600081359050614d5381614d2d565b92915050565b600060208284031215614d6f57614d6e614416565b5b6000614d7d84828501614d44565b91505092915050565b6000614d9182614440565b9050919050565b614da181614d86565b8114614dac57600080fd5b50565b600081519050614dbe81614d98565b92915050565b600060208284031215614dda57614dd9614416565b5b6000614de884828501614daf565b91505092915050565b6000604082019050614e066000830185614662565b614e136020830184614662565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050614e5881614452565b92915050565b600060208284031215614e7457614e73614416565b5b6000614e8284828501614e49565b91505092915050565b6000614e9682614892565b9050919050565b614ea681614e8b565b82525050565b6000602082019050614ec16000830184614e9d565b92915050565b60008115159050919050565b614edc81614ec7565b8114614ee757600080fd5b50565b600081519050614ef981614ed3565b92915050565b600060208284031215614f1557614f14614416565b5b6000614f2384828501614eea565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112614f5857614f57614f2c565b5b80840192508235915067ffffffffffffffff821115614f7a57614f79614f31565b5b602083019250602082023603831315614f9657614f95614f36565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614fd8826145c2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361500a57615009614f9e565b5b600182019050919050565b600081519050615024816145f6565b92915050565b6000602082840312156150405761503f614416565b5b600061504e84828501615015565b91505092915050565b615060816145c2565b811461506b57600080fd5b50565b60008135905061507d81615057565b92915050565b6000604082840312156150995761509861468c565b5b6150a36040614702565b905060006150b38482850161506e565b60008301525060206150c78482850161506e565b60208301525092915050565b600060c082840312156150e9576150e861468c565b5b6150f360a0614702565b905060006151038482850161460d565b600083015250602061511784828501615083565b602083015250606061512b8482850161460d565b604083015250608061513f8482850161460d565b60608301525060a061515384828501614d44565b60808301525092915050565b600060c0828403121561517557615174614416565b5b6000615183848285016150d3565b91505092915050565b60008151905061519b81615057565b92915050565b6000602082840312156151b7576151b6614416565b5b60006151c58482850161518c565b91505092915050565b6000604082840312156151e4576151e3614416565b5b60006151f284828501615083565b91505092915050565b600060e08201905061521060008301856148c5565b61521d60c08301846149fb565b9392505050565b60006040820190506152396000830185614e9d565b61524660208301846145cc565b9392505050565b6000615258826145c2565b9150615263836145c2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561529857615297614f9e565b5b828201905092915050565b6000815190506152b281614727565b92915050565b6000606082840312156152ce576152cd61468c565b5b6152d86060614702565b905060006152e884828501615015565b60008301525060206152fc84828501615015565b6020830152506040615310848285016152a3565b60408301525092915050565b60006060828403121561533257615331614416565b5b6000615340848285016152b8565b91505092915050565b600060408201905061535e6000830185614662565b61536b60208301846145cc565b9392505050565b600061537d826145c2565b9150615388836145c2565b92508282101561539b5761539a614f9e565b5b828203905092915050565b60006060820190506153bb6000830186614662565b6153c86020830185614662565b6153d560408301846145cc565b949350505050565b6000604082840312156153f3576153f261468c565b5b6153fd6040614702565b9050600061540d848285016152a3565b6000830152506020615421848285016152a3565b60208301525092915050565b60006040828403121561544357615442614416565b5b6000615451848285016153dd565b91505092915050565b6000604082840312156154705761546f61468c565b5b61547a6040614702565b9050600061548a8482850161518c565b600083015250602061549e8482850161518c565b60208301525092915050565b6000604082840312156154c0576154bf614416565b5b60006154ce8482850161545a565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082825260208201905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615573602a83615506565b915061557e82615517565b604082019050919050565b600060208201905081810360008301526155a281615566565b9050919050565b60006155b4826145c2565b91506155bf836145c2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155f8576155f7614f9e565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061563d826145c2565b9150615648836145c2565b92508261565857615657615603565b5b828204905092915050565b61566c8161471d565b82525050565b60006020820190506156876000830184615663565b92915050565b60006156988261471d565b91506156a38361471d565b9250827f8000000000000000000000000000000000000000000000000000000000000000018212600084121516156156de576156dd614f9e565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01821360008412161561571657615715614f9e565b5b828203905092915050565b600061572c8261471d565b91506157378361471d565b9250827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211600084136000841316161561577657615775614f9e565b5b817f800000000000000000000000000000000000000000000000000000000000000005831260008412600084131616156157b3576157b2614f9e565b5b827f800000000000000000000000000000000000000000000000000000000000000005821260008413600084121616156157f0576157ef614f9e565b5b827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff058212600084126000841216161561582d5761582c614f9e565b5b828202905092915050565b60006158438261471d565b915061584e8361471d565b92508261585e5761585d615603565b5b600160000383147f80000000000000000000000000000000000000000000000000000000000000008314161561589757615896614f9e565b5b828205905092915050565b60006158ad8261471d565b91506158b88361471d565b9250817f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038313600083121516156158f3576158f2614f9e565b5b817f800000000000000000000000000000000000000000000000000000000000000003831260008312161561592b5761592a614f9e565b5b828201905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000615992602683615506565b915061599d82615936565b604082019050919050565b600060208201905081810360008301526159c181615985565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006159fe601d83615506565b9150615a09826159c8565b602082019050919050565b60006020820190508181036000830152615a2d816159f1565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615a68578082015181840152602081019050615a4d565b83811115615a77576000848401525b50505050565b6000615a8882615a34565b615a928185615a3f565b9350615aa2818560208601615a4a565b80840191505092915050565b6000615aba8284615a7d565b915081905092915050565b600081519050919050565b6000615adb82615ac5565b615ae58185615506565b9350615af5818560208601615a4a565b615afe81614691565b840191505092915050565b60006020820190508181036000830152615b238184615ad0565b90509291505056fea264697066735822122082e9e91072630c6aecaf2986f53f9f659c308576ffcec20b0a3728c7613a1bcd64736f6c634300080f0033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "active(address)": {
        "params": {
          "product": "Product to check for"
        },
        "returns": {
          "_0": "Number of active programs"
        }
      },
      "available(address,uint256)": {
        "params": {
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "Available rewards for `programId`"
        }
      },
      "claim(address,uint256[])": {
        "params": {
          "product": "Product to claim rewards for",
          "programIds": "Programs to claim rewards for"
        }
      },
      "claim(address[],uint256[][])": {
        "params": {
          "products": "Products to claim rewards for",
          "programIds": "Programs to claim rewards for"
        }
      },
      "claimFee(address[])": {
        "params": {
          "tokens": "Tokens to claim fees for"
        }
      },
      "claimFor(address,address,uint256[])": {
        "params": {
          "account": "Account to claim rewards for",
          "product": "Product to claim rewards for",
          "programIds": "Programs to claim rewards for"
        }
      },
      "complete(address,uint256)": {
        "details": "Must be called as the program owner",
        "params": {
          "product": "Product that the program is running on",
          "programId": "Program to complete early"
        }
      },
      "count(address)": {
        "params": {
          "product": "Product to check for"
        },
        "returns": {
          "_0": "Number of programs (inactive or active)"
        }
      },
      "create(address,(uint256,(uint256,uint256),uint256,uint256,address))": {
        "details": "Must be called as the product or protocol owner",
        "params": {
          "product": "The product to create the new program on",
          "programInfo": "Parameters for the new program"
        },
        "returns": {
          "programId": "New program's ID"
        }
      },
      "initialize(address)": {
        "details": "Must be called atomically as part of the upgradeable proxy deployment to      avoid front-running",
        "params": {
          "controller_": "Factory contract address"
        }
      },
      "owner(address,uint256)": {
        "params": {
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "The owner of `programId`"
        }
      },
      "programInfos(address,uint256)": {
        "params": {
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "Program info"
        }
      },
      "sync((uint256,uint256,int256))": {
        "details": "Called every settle() from each product",
        "params": {
          "currentOracleVersion": "The preloaded current oracle version"
        }
      },
      "syncAccount(address,(uint256,uint256,int256))": {
        "details": "Called immediately proceeding a position update in the corresponding product",
        "params": {
          "account": "Account to sync",
          "currentOracleVersion": "The preloaded current oracle version"
        }
      },
      "treasury(address,uint256)": {
        "params": {
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "The treasury of `programId`"
        }
      },
      "unclaimed(address,address,uint256)": {
        "params": {
          "account": "Account to return for",
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "`account`'s total unclaimed rewards for `programId`"
        }
      },
      "versionComplete(address,uint256)": {
        "params": {
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "The version completed for `programId`"
        }
      },
      "versionStarted(address,uint256)": {
        "params": {
          "product": "Product to return for",
          "programId": "Program to return for"
        },
        "returns": {
          "_0": "The version started for `programId`"
        }
      }
    },
    "stateVariables": {
      "_products": {
        "details": "Product management state"
      },
      "fees": {
        "details": "Fees that have been collected, but remain unclaimed"
      }
    },
    "title": "Incentivizer",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "active(address)": {
        "notice": "Returns the quantity of active programs for a given product"
      },
      "available(address,uint256)": {
        "notice": "Returns available rewards for a specific program"
      },
      "claim(address,uint256[])": {
        "notice": "Claims all of `msg.sender`'s rewards for `product` programs"
      },
      "claim(address[],uint256[][])": {
        "notice": "Claims all of `msg.sender`'s rewards for a specific program"
      },
      "claimFee(address[])": {
        "notice": "Claims all `tokens` fees to the protocol treasury"
      },
      "claimFor(address,address,uint256[])": {
        "notice": "Claims all of `account`'s rewards for `product` programs"
      },
      "complete(address,uint256)": {
        "notice": "Completes an in-progress program early"
      },
      "count(address)": {
        "notice": "Returns the quantity of programs for a given product"
      },
      "create(address,(uint256,(uint256,uint256),uint256,uint256,address))": {
        "notice": "Creates a new incentive program"
      },
      "initialize(address)": {
        "notice": "Initializes the contract state"
      },
      "owner(address,uint256)": {
        "notice": "Returns the owner of a specific program"
      },
      "programInfos(address,uint256)": {
        "notice": "Returns program info for program `programId`"
      },
      "sync((uint256,uint256,int256))": {
        "notice": "Starts and completes programs as they become available"
      },
      "syncAccount(address,(uint256,uint256,int256))": {
        "notice": "Settles unsettled balance for `account`"
      },
      "treasury(address,uint256)": {
        "notice": "Returns the treasury of a specific program"
      },
      "unclaimed(address,address,uint256)": {
        "notice": "Returns `account`'s total unclaimed rewards for a specific program"
      },
      "versionComplete(address,uint256)": {
        "notice": "Returns the version completed for a specific program"
      },
      "versionStarted(address,uint256)": {
        "notice": "Returns the version started for a specific program"
      }
    },
    "notice": "Manages logic and state for all incentive programs in the protocol.",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 12843,
        "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
        "label": "_products",
        "offset": 0,
        "slot": "0",
        "type": "t_mapping(t_contract(IProduct)16614,t_struct(ProductManager)13689_storage)"
      },
      {
        "astId": 12850,
        "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
        "label": "fees",
        "offset": 0,
        "slot": "1",
        "type": "t_mapping(t_userDefinedValueType(Token18)4038,t_userDefinedValueType(UFixed18)3251)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_bytes32)dyn_storage": {
        "base": "t_bytes32",
        "encoding": "dynamic_array",
        "label": "bytes32[]",
        "numberOfBytes": "32"
      },
      "t_array(t_struct(ProgramInfo)18168_storage)dyn_storage": {
        "base": "t_struct(ProgramInfo)18168_storage",
        "encoding": "dynamic_array",
        "label": "struct ProgramInfo[]",
        "numberOfBytes": "32"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_contract(IProduct)16614": {
        "encoding": "inplace",
        "label": "contract IProduct",
        "numberOfBytes": "20"
      },
      "t_mapping(t_address,t_struct(UintSet)10284_storage)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => struct EnumerableSet.UintSet)",
        "numberOfBytes": "32",
        "value": "t_struct(UintSet)10284_storage"
      },
      "t_mapping(t_address,t_uint256)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_mapping(t_address,t_userDefinedValueType(UFixed18)3251)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => UFixed18)",
        "numberOfBytes": "32",
        "value": "t_userDefinedValueType(UFixed18)3251"
      },
      "t_mapping(t_bytes32,t_uint256)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_mapping(t_contract(IProduct)16614,t_struct(ProductManager)13689_storage)": {
        "encoding": "mapping",
        "key": "t_contract(IProduct)16614",
        "label": "mapping(contract IProduct => struct ProductManager)",
        "numberOfBytes": "32",
        "value": "t_struct(ProductManager)13689_storage"
      },
      "t_mapping(t_uint256,t_struct(Program)14284_storage)": {
        "encoding": "mapping",
        "key": "t_uint256",
        "label": "mapping(uint256 => struct Program)",
        "numberOfBytes": "32",
        "value": "t_struct(Program)14284_storage"
      },
      "t_mapping(t_userDefinedValueType(Token18)4038,t_userDefinedValueType(UFixed18)3251)": {
        "encoding": "mapping",
        "key": "t_userDefinedValueType(Token18)4038",
        "label": "mapping(Token18 => UFixed18)",
        "numberOfBytes": "32",
        "value": "t_userDefinedValueType(UFixed18)3251"
      },
      "t_struct(Position)17506_storage": {
        "encoding": "inplace",
        "label": "struct Position",
        "members": [
          {
            "astId": 17501,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "maker",
            "offset": 0,
            "slot": "0",
            "type": "t_userDefinedValueType(UFixed18)3251"
          },
          {
            "astId": 17505,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "taker",
            "offset": 0,
            "slot": "1",
            "type": "t_userDefinedValueType(UFixed18)3251"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_struct(ProductManager)13689_storage": {
        "encoding": "inplace",
        "label": "struct ProductManager",
        "members": [
          {
            "astId": 13667,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "programInfos",
            "offset": 0,
            "slot": "0",
            "type": "t_array(t_struct(ProgramInfo)18168_storage)dyn_storage"
          },
          {
            "astId": 13673,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "programs",
            "offset": 0,
            "slot": "1",
            "type": "t_mapping(t_uint256,t_struct(Program)14284_storage)"
          },
          {
            "astId": 13677,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "activePrograms",
            "offset": 0,
            "slot": "2",
            "type": "t_struct(UintSet)10284_storage"
          },
          {
            "astId": 13683,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "activeProgramsFor",
            "offset": 0,
            "slot": "4",
            "type": "t_mapping(t_address,t_struct(UintSet)10284_storage)"
          },
          {
            "astId": 13688,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "nextProgramFor",
            "offset": 0,
            "slot": "5",
            "type": "t_mapping(t_address,t_uint256)"
          }
        ],
        "numberOfBytes": "192"
      },
      "t_struct(Program)14284_storage": {
        "encoding": "inplace",
        "label": "struct Program",
        "members": [
          {
            "astId": 14273,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "settled",
            "offset": 0,
            "slot": "0",
            "type": "t_mapping(t_address,t_userDefinedValueType(UFixed18)3251)"
          },
          {
            "astId": 14277,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "available",
            "offset": 0,
            "slot": "1",
            "type": "t_userDefinedValueType(UFixed18)3251"
          },
          {
            "astId": 14280,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "versionStarted",
            "offset": 0,
            "slot": "2",
            "type": "t_uint256"
          },
          {
            "astId": 14283,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "versionComplete",
            "offset": 0,
            "slot": "3",
            "type": "t_uint256"
          }
        ],
        "numberOfBytes": "128"
      },
      "t_struct(ProgramInfo)18168_storage": {
        "encoding": "inplace",
        "label": "struct ProgramInfo",
        "members": [
          {
            "astId": 18153,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "coordinatorId",
            "offset": 0,
            "slot": "0",
            "type": "t_uint256"
          },
          {
            "astId": 18157,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "amount",
            "offset": 0,
            "slot": "1",
            "type": "t_struct(Position)17506_storage"
          },
          {
            "astId": 18160,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "start",
            "offset": 0,
            "slot": "3",
            "type": "t_uint256"
          },
          {
            "astId": 18163,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "duration",
            "offset": 0,
            "slot": "4",
            "type": "t_uint256"
          },
          {
            "astId": 18167,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "token",
            "offset": 0,
            "slot": "5",
            "type": "t_userDefinedValueType(Token18)4038"
          }
        ],
        "numberOfBytes": "192"
      },
      "t_struct(Set)9826_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.Set",
        "members": [
          {
            "astId": 9821,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "_values",
            "offset": 0,
            "slot": "0",
            "type": "t_array(t_bytes32)dyn_storage"
          },
          {
            "astId": 9825,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "_indexes",
            "offset": 0,
            "slot": "1",
            "type": "t_mapping(t_bytes32,t_uint256)"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_struct(UintSet)10284_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.UintSet",
        "members": [
          {
            "astId": 10283,
            "contract": "contracts/incentivizer/Incentivizer.sol:Incentivizer",
            "label": "_inner",
            "offset": 0,
            "slot": "0",
            "type": "t_struct(Set)9826_storage"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      },
      "t_userDefinedValueType(Token18)4038": {
        "encoding": "inplace",
        "label": "Token18",
        "numberOfBytes": "20"
      },
      "t_userDefinedValueType(UFixed18)3251": {
        "encoding": "inplace",
        "label": "UFixed18",
        "numberOfBytes": "32"
      }
    }
  }
}
