diff --git a/packages/perennial-vaults/deploy/02_deploy_vault_bravo.ts b/packages/perennial-vaults/deploy/02_deploy_vault_bravo.ts index acd9a674..514da03a 100644 --- a/packages/perennial-vaults/deploy/02_deploy_vault_bravo.ts +++ b/packages/perennial-vaults/deploy/02_deploy_vault_bravo.ts @@ -20,7 +20,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const controller = (await get('Controller_Proxy')).address const long = (await get('Product_LongArbitrum')).address const short = (await get('Product_ShortArbitrum')).address - const targetLeverage = ethers.utils.parseEther('2') + const targetLeverage = ethers.utils.parseEther('1') const maxCollateral = ethers.utils.parseEther('500000') const vaultImpl = await deploy('PerennialVaultBravo_Impl', { diff --git a/packages/perennial-vaults/deployments/arbitrum/PerennialVaultBravo_Impl.json b/packages/perennial-vaults/deployments/arbitrum/PerennialVaultBravo_Impl.json index ee9a6a91..5bbae43c 100644 --- a/packages/perennial-vaults/deployments/arbitrum/PerennialVaultBravo_Impl.json +++ b/packages/perennial-vaults/deployments/arbitrum/PerennialVaultBravo_Impl.json @@ -1,5 +1,5 @@ { - "address": "0xda17b128BFd23112E946FB4e7BA162029D7d1CdE", + "address": "0xDeEb41dC9C86575aa093A6b091e92B8256d8FD31", "abi": [ { "inputs": [ @@ -737,19 +737,19 @@ "type": "function" } ], - "transactionHash": "0x130cb29a4885f8b78eae3f9c1d2934c6d36dc44ea709c9209d933c63fcf1f774", + "transactionHash": "0x60022824ff2b1ad055454dc77236e58fc9e35ac42ec86c470995a19f78380c4e", "receipt": { "to": null, "from": "0x66a7fDB96C583c59597de16d8b2B989231415339", - "contractAddress": "0xda17b128BFd23112E946FB4e7BA162029D7d1CdE", + "contractAddress": "0xDeEb41dC9C86575aa093A6b091e92B8256d8FD31", "transactionIndex": 1, - "gasUsed": "16815051", + "gasUsed": "42284941", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4ffd2fa03f5e0b9518d1eb1db2dc6c637a71a895f1024c85cf856f1a7fea0587", - "transactionHash": "0x130cb29a4885f8b78eae3f9c1d2934c6d36dc44ea709c9209d933c63fcf1f774", + "blockHash": "0x3eda046445759286afc45df15fbfe50aeca1174f00c918e97273767b2af7f4f5", + "transactionHash": "0x60022824ff2b1ad055454dc77236e58fc9e35ac42ec86c470995a19f78380c4e", "logs": [], - "blockNumber": 104499589, - "cumulativeGasUsed": "16815051", + "blockNumber": 108209112, + "cumulativeGasUsed": "42284941", "status": 1, "byzantium": true }, @@ -758,10 +758,10 @@ "0xA59eF0208418559770a48D7ae4f260A28763167B", "0x5E660B7B8357059241EAEc143e1e68A5A108D035", "0x4e67a8a428206Af5a6AC00Ba08a67Ce827182985", - "2000000000000000000", + "1000000000000000000", "500000000000000000000000" ], - "numDeployments": 2, + "numDeployments": 3, "solcInputHash": "f997dc38fb3c14c95e0fe0c71ee65176", "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"Token18\",\"name\":\"asset_\",\"type\":\"address\"},{\"internalType\":\"contract IController\",\"name\":\"controller_\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"long_\",\"type\":\"address\"},{\"internalType\":\"contract IProduct\",\"name\":\"short_\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"targetLeverage_\",\"type\":\"uint256\"},{\"internalType\":\"UFixed18\",\"name\":\"maxCollateral_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BalancedVaultDepositLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BalancedVaultRedemptionLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Fixed18OverflowError\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"Claim\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"targetCollateral\",\"type\":\"uint256\"}],\"name\":\"CollateralUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract IProduct\",\"name\":\"product\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"targetPosition\",\"type\":\"uint256\"}],\"name\":\"PositionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"Redemption\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"UFixed18\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"asset\",\"outputs\":[{\"internalType\":\"Token18\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract ICollateral\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"controller\",\"outputs\":[{\"internalType\":\"contract IController\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"UFixed18\",\"name\":\"shares\",\"type\":\"uint256\"}],\"name\":\"convertToAssets\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"UFixed18\",\"name\":\"assets\",\"type\":\"uint256\"}],\"name\":\"convertToShares\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"UFixed18\",\"name\":\"assets\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"long\",\"outputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxCollateral\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"maxDeposit\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"maxRedeem\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"UFixed18\",\"name\":\"shares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"redeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"short\",\"outputs\":[{\"internalType\":\"contract IProduct\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sync\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetLeverage\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalAssets\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalUnclaimed\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"UFixed18\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"unclaimed\",\"outputs\":[{\"internalType\":\"UFixed18\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap the maximum amount of assets in the vault. The vault has a \\\"delayed mint\\\" mechanism for shares on deposit. After depositing to the vault, a user must wait until the next settlement of the underlying products in order for shares to be reflected in the getters. The shares will be fully reflected in contract state when the next settlement occurs on the vault itself. Similarly, when redeeming shares, underlying assets are not claimable until a settlement occurs. Each state changing interaction triggers the `settle` flywheel in order to bring the vault to the desired state. In the event that there is not a settlement for a long period of time, keepers can call the `sync` method to force settlement and rebalancing. This is most useful to prevent vault liquidation due to PnL changes causing the vault to be in an unhealthy state (far away from target leverage)\",\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"params\":{\"amount\":\"Amount of shares that spender can operate on\",\"spender\":\"Address which can spend operate on shares\"},\"returns\":{\"_0\":\"bool true if the approval was successful, otherwise reverts\"}},\"balanceOf(address)\":{\"params\":{\"account\":\"Account to query balance of\"},\"returns\":{\"_0\":\"Number of shares held by `account`\"}},\"claim(address)\":{\"params\":{\"account\":\"The account to claim for\"}},\"convertToAssets(uint256)\":{\"params\":{\"shares\":\"Number of shares to convert to assets\"},\"returns\":{\"_0\":\"Amount of assets for the given shares\"}},\"convertToShares(uint256)\":{\"params\":{\"assets\":\"Number of assets to convert to shares\"},\"returns\":{\"_0\":\"Amount of shares for the given assets\"}},\"decimals()\":{\"returns\":{\"_0\":\"Decimal places of the share share token\"}},\"deposit(uint256,address)\":{\"params\":{\"account\":\"The account to deposit on behalf of\",\"assets\":\"The amount of assets to deposit\"}},\"initialize(string,string)\":{\"params\":{\"name_\":\"ERC20 asset name\",\"symbol_\":\"ERC20 asset symbol\"}},\"maxDeposit(address)\":{\"details\":\"Only exact when vault is synced, otherwise approximate\",\"returns\":{\"_0\":\"Maximum available deposit amount\"}},\"maxRedeem(address)\":{\"details\":\"Only exact when vault is synced, otherwise approximate\",\"params\":{\"account\":\"The account to redeem for\"},\"returns\":{\"_0\":\"Maximum available redeemable amount\"}},\"redeem(uint256,address)\":{\"details\":\"Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets If account is not msg.sender, requires prior spending approval\",\"params\":{\"account\":\"The account to redeem on behalf of\",\"shares\":\"The amount of shares to redeem\"}},\"sync()\":{\"details\":\"Should be called by a keeper when the vault approaches a liquidation state on either side\"},\"totalAssets()\":{\"returns\":{\"_0\":\"Amount of assets held by the vault\"}},\"totalSupply()\":{\"returns\":{\"_0\":\"Amount of shares currently issued\"}},\"totalUnclaimed()\":{\"returns\":{\"_0\":\"Total unclaimed assets in vault\"}},\"transfer(address,uint256)\":{\"params\":{\"amount\":\"Amount of shares to send\",\"to\":\"Address to send shares to\"},\"returns\":{\"_0\":\"bool true if the transfer was successful, otherwise reverts\"}},\"transferFrom(address,address,uint256)\":{\"params\":{\"amount\":\"Amount of shares to send\",\"from\":\"Address to send shares from\",\"to\":\"Address to send shares to\"},\"returns\":{\"_0\":\"bool true if the transfer was successful, otherwise reverts\"}},\"unclaimed(address)\":{\"params\":{\"account\":\"Account to query unclaimed balance of\"},\"returns\":{\"_0\":\"`account`'s unclaimed assets\"}}},\"stateVariables\":{\"_balanceOf\":{\"details\":\"Mapping of shares of the vault per user\"},\"_deposit\":{\"details\":\"Deposits that have not been settled, or have been settled but not yet processed by this contract\"},\"_deposits\":{\"details\":\"Mapping of pending (not yet converted to shares) per user\"},\"_latestVersion\":{\"details\":\"The latest version that a pending deposit or redemption has been placed\"},\"_latestVersions\":{\"details\":\"Mapping of the latest version that a pending deposit or redemption has been placed per user\"},\"_redemption\":{\"details\":\"Redemptions that have not been settled, or have been settled but not yet processed by this contract\"},\"_redemptions\":{\"details\":\"Mapping of pending (not yet withdrawn) per user\"},\"_totalSupply\":{\"details\":\"Total number of shares across all users\"},\"_totalUnclaimed\":{\"details\":\"Mapping of unclaimed underlying of the vault per user\"},\"_unclaimed\":{\"details\":\"Mapping of unclaimed underlying of the vault per user\"},\"_versions\":{\"details\":\"Mapping of versions of the vault state at a given oracle version\"},\"allowance\":{\"details\":\"Mapping of allowance across all users\"},\"asset\":{\"details\":\"The underlying asset of the vault\"},\"collateral\":{\"details\":\"The address of the Perennial collateral contract\"},\"controller\":{\"details\":\"The address of the Perennial controller contract\"},\"long\":{\"details\":\"The address of the Perennial product on the long side\"},\"maxCollateral\":{\"details\":\"The collateral cap for the vault\"},\"name\":{\"details\":\"The ERC20 name of the vault\"},\"short\":{\"details\":\"The address of the Perennial product on the short side\"},\"symbol\":{\"details\":\"The ERC20 symbol of the vault\"},\"targetLeverage\":{\"details\":\"The target leverage amount for the vault\"}},\"title\":\"BalancedVault\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"approve(address,uint256)\":{\"notice\":\"Sets `amount` as the allowance of `spender` over the caller's shares\"},\"balanceOf(address)\":{\"notice\":\"Number of shares held by `account`\"},\"claim(address)\":{\"notice\":\"Claims all claimable assets for account, sending assets to account\"},\"convertToAssets(uint256)\":{\"notice\":\"Converts a given amount of shares to assets\"},\"convertToShares(uint256)\":{\"notice\":\"Converts a given amount of assets to shares\"},\"decimals()\":{\"notice\":\"Returns the decimals places of the share token\"},\"deposit(uint256,address)\":{\"notice\":\"Deposits `assets` assets into the vault, returning shares to `account` after the deposit settles.\"},\"initialize(string,string)\":{\"notice\":\"Initializes the contract state\"},\"maxDeposit(address)\":{\"notice\":\"The maximum available deposit amount\"},\"maxRedeem(address)\":{\"notice\":\"The maximum available redeemable amount\"},\"redeem(uint256,address)\":{\"notice\":\"Redeems `shares` shares from the vault\"},\"sync()\":{\"notice\":\"Rebalances the collateral and position of the vault without a deposit or withdraw\"},\"totalAssets()\":{\"notice\":\"The total amount of assets currently held by the vault\"},\"totalSupply()\":{\"notice\":\"The total amount of shares currently issued\"},\"totalUnclaimed()\":{\"notice\":\"Total unclaimed assets in vault\"},\"transfer(address,uint256)\":{\"notice\":\"Moves `amount` shares from the caller's account to `to`\"},\"transferFrom(address,address,uint256)\":{\"notice\":\"Moves `amount` shares from `from to `to`\"},\"unclaimed(address)\":{\"notice\":\"`account`'s unclaimed assets\"}},\"notice\":\"ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BalancedVault.sol\":\"BalancedVault\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@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\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"../interfaces/IEmptySetReserve.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 RESERVE() external view returns (IEmptySetReserve); // solhint-disable-line func-name-mixedcase\\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 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\":\"0xb9c0b0fc0dfcd44492b029ede04d304f6906b030cb925dc0fc2579e8c58d9734\",\"license\":\"Apache-2.0\"},\"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\ninterface IEmptySetReserve {\\n event Redeem(address indexed account, uint256 costAmount, uint256 redeemAmount);\\n event Mint(address indexed account, uint256 mintAmount, uint256 costAmount);\\n event Repay(address indexed account, uint256 repayAmount);\\n\\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\":\"0xdb96e26082a471c7803e892ecd8d2877f23cd9e31f13a3e407dd5f8909078864\",\"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 Error for invalid oracle round\\n error InvalidOracleRound();\\n\\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\":\"0x11e8ebb40917dcce08a6366e6fa8d25b037552d4ea66b96c13e6f45b1f817c52\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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 error CollateralAccountLiquidatingError(address account);\\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\":\"0x6fb67eb5fc3ed4a74522677da3349d75105389369892756a60fcab4c901d352b\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/contracts/interfaces/IMultiInvoker.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/root/token/types/Token6.sol\\\";\\nimport \\\"@equilibria/root/token/types/Token18.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/interfaces/IBatcher.sol\\\";\\nimport \\\"@equilibria/emptyset-batcher/interfaces/IEmptySetReserve.sol\\\";\\n\\nimport \\\"./IController.sol\\\";\\nimport \\\"./ICollateral.sol\\\";\\nimport \\\"./IProduct.sol\\\";\\n\\ninterface IPerennialVault {\\n event Deposit(address indexed sender, address indexed account, uint256 version, UFixed18 assets);\\n event Redemption(address indexed sender, address indexed account, uint256 version, UFixed18 shares);\\n event Claim(address indexed sender, address indexed account, UFixed18 assets);\\n\\n function deposit(UFixed18 assets, address account) external;\\n function redeem(UFixed18 shares, address account) external;\\n function claim(address account) external;\\n}\\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 VAULT_DEPOSIT,\\n VAULT_REDEEM,\\n VAULT_CLAIM,\\n VAULT_WRAP_AND_DEPOSIT\\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 (IBatcher);\\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\":\"0xf54645562fc10f688ac76328858ed1299e8f30eb1be4f4196f016f9851c6c3c9\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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 ParamProviderInvalidParamValue();\\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\":\"0x21584bd07296eb4e8bd6076fd20afad320e781c19c60b479c9340c69b0f37517\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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 event OracleUpdated(address newOracle, uint256 oracleVersion);\\n\\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\":\"0x803d22f7513c2c5186f77f6bc7cc34673ed762e40f106f9aef512eb9b57018af\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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 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 function updateOracle(IOracleProvider newOracle) external;\\n}\\n\",\"keccak256\":\"0x8e53ea97d8d59519adcbc2aa3600b5e51de1d59efec485a88eca8b574a35a00f\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/contracts/interfaces/types/PayoffDefinition.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\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\":\"0x99f9b5d5facba16885a375beac2a05129e7b23a8cceee048a7affd7f12a18a8f\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/contracts/interfaces/types/PendingFeeUpdates.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\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\":\"0xd98c681bdd6e1808e311615b3c4ac3b557ce5ec461f7b1cc645a51590eaf6f93\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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\"},\"@equilibria/perennial/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 self.oracleVersion != 0 && 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\":\"0x0c9d701afdb67f0e134a5a0ba33ebb031fa146cb52b5871cbcd6522d9579264b\",\"license\":\"Apache-2.0\"},\"@equilibria/perennial/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\"},\"@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/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/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.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 function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\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\":\"0x9b72f93be69ca894d8492c244259615c4a742afc8d63720dbc8bb81087d9b238\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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 functionCallWithValue(target, data, 0, \\\"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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or 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 _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\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 /// @solidity memory-safe-assembly\\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\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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 enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\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 == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/BalancedVault.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity 0.8.17;\\n\\nimport \\\"./interfaces/IBalancedVault.sol\\\";\\nimport \\\"@equilibria/root/control/unstructured/UInitializable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\n\\n/**\\n * @title BalancedVault\\n * @notice ERC4626 vault that manages a 50-50 position between long-short markets of the same payoff on Perennial.\\n * @dev Vault deploys and rebalances collateral between the corresponding long and short markets, while attempting to\\n * maintain `targetLeverage` with its open positions at any given time. Deposits are only gated in so much as to cap\\n * the maximum amount of assets in the vault.\\n *\\n * The vault has a \\\"delayed mint\\\" mechanism for shares on deposit. After depositing to the vault, a user must wait\\n * until the next settlement of the underlying products in order for shares to be reflected in the getters.\\n * The shares will be fully reflected in contract state when the next settlement occurs on the vault itself.\\n * Similarly, when redeeming shares, underlying assets are not claimable until a settlement occurs.\\n * Each state changing interaction triggers the `settle` flywheel in order to bring the vault to the\\n * desired state.\\n * In the event that there is not a settlement for a long period of time, keepers can call the `sync` method to\\n * force settlement and rebalancing. This is most useful to prevent vault liquidation due to PnL changes\\n * causing the vault to be in an unhealthy state (far away from target leverage)\\n */\\ncontract BalancedVault is IBalancedVault, UInitializable {\\n UFixed18 constant private TWO = UFixed18.wrap(2e18);\\n\\n /// @dev The address of the Perennial controller contract\\n IController public immutable controller;\\n\\n /// @dev The address of the Perennial collateral contract\\n ICollateral public immutable collateral;\\n\\n /// @dev The address of the Perennial product on the long side\\n IProduct public immutable long;\\n\\n /// @dev The address of the Perennial product on the short side\\n IProduct public immutable short;\\n\\n /// @dev The target leverage amount for the vault\\n UFixed18 public immutable targetLeverage;\\n\\n /// @dev The collateral cap for the vault\\n UFixed18 public immutable maxCollateral;\\n\\n /// @dev The underlying asset of the vault\\n Token18 public immutable asset;\\n\\n /// @dev The ERC20 name of the vault\\n string public name;\\n\\n /// @dev The ERC20 symbol of the vault\\n string public symbol;\\n\\n /// @dev Mapping of allowance across all users\\n mapping(address => mapping(address => UFixed18)) public allowance;\\n\\n /// @dev Mapping of shares of the vault per user\\n mapping(address => UFixed18) private _balanceOf;\\n\\n /// @dev Total number of shares across all users\\n UFixed18 private _totalSupply;\\n\\n /// @dev Mapping of unclaimed underlying of the vault per user\\n mapping(address => UFixed18) private _unclaimed;\\n\\n /// @dev Mapping of unclaimed underlying of the vault per user\\n UFixed18 private _totalUnclaimed;\\n\\n /// @dev Deposits that have not been settled, or have been settled but not yet processed by this contract\\n UFixed18 private _deposit;\\n\\n /// @dev Redemptions that have not been settled, or have been settled but not yet processed by this contract\\n UFixed18 private _redemption;\\n\\n /// @dev The latest version that a pending deposit or redemption has been placed\\n uint256 private _latestVersion;\\n\\n /// @dev Mapping of pending (not yet converted to shares) per user\\n mapping(address => UFixed18) private _deposits;\\n\\n /// @dev Mapping of pending (not yet withdrawn) per user\\n mapping(address => UFixed18) private _redemptions;\\n\\n /// @dev Mapping of the latest version that a pending deposit or redemption has been placed per user\\n mapping(address => uint256) private _latestVersions;\\n\\n /// @dev Mapping of versions of the vault state at a given oracle version\\n mapping(uint256 => Version) private _versions;\\n\\n constructor(\\n Token18 asset_,\\n IController controller_,\\n IProduct long_,\\n IProduct short_,\\n UFixed18 targetLeverage_,\\n UFixed18 maxCollateral_\\n ) {\\n asset = asset_;\\n controller = controller_;\\n collateral = controller_.collateral();\\n long = long_;\\n short = short_;\\n targetLeverage = targetLeverage_;\\n maxCollateral = maxCollateral_;\\n }\\n\\n /**\\n * @notice Initializes the contract state\\n * @param name_ ERC20 asset name\\n * @param symbol_ ERC20 asset symbol\\n */\\n function initialize(string memory name_, string memory symbol_) external initializer(1) {\\n name = name_;\\n symbol = symbol_;\\n\\n asset.approve(address(collateral));\\n }\\n\\n /**\\n * @notice Rebalances the collateral and position of the vault without a deposit or withdraw\\n * @dev Should be called by a keeper when the vault approaches a liquidation state on either side\\n */\\n function sync() external {\\n (VersionContext memory context, ) = _settle(address(0));\\n _rebalance(context, UFixed18Lib.ZERO);\\n }\\n\\n /**\\n * @notice Deposits `assets` assets into the vault, returning shares to `account` after the deposit settles.\\n * @param assets The amount of assets to deposit\\n * @param account The account to deposit on behalf of\\n */\\n function deposit(UFixed18 assets, address account) external {\\n (VersionContext memory context, ) = _settle(account);\\n if (assets.gt(_maxDepositAtVersion(context))) revert BalancedVaultDepositLimitExceeded();\\n\\n _deposit = _deposit.add(assets);\\n _latestVersion = context.version;\\n _deposits[account] = _deposits[account].add(assets);\\n _latestVersions[account] = context.version;\\n emit Deposit(msg.sender, account, context.version, assets);\\n\\n asset.pull(msg.sender, assets);\\n\\n _rebalance(context, UFixed18Lib.ZERO);\\n }\\n\\n /**\\n * @notice Redeems `shares` shares from the vault\\n * @dev Does not return any assets to the user due to delayed settlement. Use `claim` to claim assets\\n * If account is not msg.sender, requires prior spending approval\\n * @param shares The amount of shares to redeem\\n * @param account The account to redeem on behalf of\\n */\\n function redeem(UFixed18 shares, address account) external {\\n if (msg.sender != account) _consumeAllowance(account, msg.sender, shares);\\n\\n (VersionContext memory context, VersionContext memory accountContext) = _settle(account);\\n if (shares.gt(_maxRedeemAtVersion(context, accountContext, account))) revert BalancedVaultRedemptionLimitExceeded();\\n\\n _redemption = _redemption.add(shares);\\n _latestVersion = context.version;\\n _redemptions[account] = _redemptions[account].add(shares);\\n _latestVersions[account] = context.version;\\n emit Redemption(msg.sender, account, context.version, shares);\\n\\n _burn(account, shares);\\n\\n _rebalance(context, UFixed18Lib.ZERO);\\n }\\n\\n /**\\n * @notice Claims all claimable assets for account, sending assets to account\\n * @param account The account to claim for\\n */\\n function claim(address account) external {\\n (VersionContext memory context, ) = _settle(account);\\n\\n UFixed18 unclaimedAmount = _unclaimed[account];\\n UFixed18 unclaimedTotal = _totalUnclaimed;\\n _unclaimed[account] = UFixed18Lib.ZERO;\\n _totalUnclaimed = unclaimedTotal.sub(unclaimedAmount);\\n emit Claim(msg.sender, account, unclaimedAmount);\\n\\n // pro-rate if vault has less collateral than unclaimed\\n UFixed18 claimAmount = unclaimedAmount;\\n (UFixed18 longCollateral, UFixed18 shortCollateral, UFixed18 idleCollateral) = _collateral();\\n UFixed18 totalCollateral = longCollateral.add(shortCollateral).add(idleCollateral);\\n if (totalCollateral.lt(unclaimedTotal)) claimAmount = claimAmount.muldiv(totalCollateral, unclaimedTotal);\\n\\n _rebalance(context, claimAmount);\\n\\n asset.push(account, claimAmount);\\n }\\n\\n /**\\n * @notice Sets `amount` as the allowance of `spender` over the caller's shares\\n * @param spender Address which can spend operate on shares\\n * @param amount Amount of shares that spender can operate on\\n * @return bool true if the approval was successful, otherwise reverts\\n */\\n function approve(address spender, UFixed18 amount) external returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n emit Approval(msg.sender, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Moves `amount` shares from the caller's account to `to`\\n * @param to Address to send shares to\\n * @param amount Amount of shares to send\\n * @return bool true if the transfer was successful, otherwise reverts\\n */\\n function transfer(address to, UFixed18 amount) external returns (bool) {\\n _settle(msg.sender);\\n _transfer(msg.sender, to, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Moves `amount` shares from `from to `to`\\n * @param from Address to send shares from\\n * @param to Address to send shares to\\n * @param amount Amount of shares to send\\n * @return bool true if the transfer was successful, otherwise reverts\\n */\\n function transferFrom(address from, address to, UFixed18 amount) external returns (bool) {\\n _settle(from);\\n _consumeAllowance(from, msg.sender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @notice Returns the decimals places of the share token\\n * @return Decimal places of the share share token\\n */\\n function decimals() external pure returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @notice The maximum available deposit amount\\n * @dev Only exact when vault is synced, otherwise approximate\\n * @return Maximum available deposit amount\\n */\\n function maxDeposit(address) external view returns (UFixed18) {\\n (VersionContext memory context, ) = _loadContextForRead(address(0));\\n return _maxDepositAtVersion(context);\\n }\\n\\n /**\\n * @notice The maximum available redeemable amount\\n * @dev Only exact when vault is synced, otherwise approximate\\n * @param account The account to redeem for\\n * @return Maximum available redeemable amount\\n */\\n function maxRedeem(address account) external view returns (UFixed18) {\\n (VersionContext memory context, VersionContext memory accountContext) = _loadContextForRead(account);\\n return _maxRedeemAtVersion(context, accountContext, account);\\n }\\n\\n /**\\n * @notice The total amount of assets currently held by the vault\\n * @return Amount of assets held by the vault\\n */\\n function totalAssets() external view returns (UFixed18) {\\n (VersionContext memory context, ) = _loadContextForRead(address(0));\\n return _totalAssetsAtVersion(context);\\n }\\n\\n /**\\n * @notice The total amount of shares currently issued\\n * @return Amount of shares currently issued\\n */\\n function totalSupply() external view returns (UFixed18) {\\n (VersionContext memory context, ) = _loadContextForRead(address(0));\\n return _totalSupplyAtVersion(context);\\n }\\n\\n /**\\n * @notice Number of shares held by `account`\\n * @param account Account to query balance of\\n * @return Number of shares held by `account`\\n */\\n function balanceOf(address account) external view returns (UFixed18) {\\n (, VersionContext memory accountContext) = _loadContextForRead(account);\\n return _balanceOfAtVersion(accountContext, account);\\n }\\n\\n /**\\n * @notice Total unclaimed assets in vault\\n * @return Total unclaimed assets in vault\\n */\\n function totalUnclaimed() external view returns (UFixed18) {\\n (VersionContext memory context, ) = _loadContextForRead(address(0));\\n return _totalUnclaimedAtVersion(context);\\n }\\n\\n /**\\n * @notice `account`'s unclaimed assets\\n * @param account Account to query unclaimed balance of\\n * @return `account`'s unclaimed assets\\n */\\n function unclaimed(address account) external view returns (UFixed18) {\\n (, VersionContext memory accountContext) = _loadContextForRead(account);\\n return _unclaimedAtVersion(accountContext, account);\\n }\\n\\n /**\\n * @notice Converts a given amount of assets to shares\\n * @param assets Number of assets to convert to shares\\n * @return Amount of shares for the given assets\\n */\\n function convertToShares(UFixed18 assets) external view returns (UFixed18) {\\n (VersionContext memory context, ) = _loadContextForRead(address(0));\\n (context.latestCollateral, context.latestShares) =\\n (_totalAssetsAtVersion(context), _totalSupplyAtVersion(context));\\n return _convertToSharesAtVersion(context, assets);\\n }\\n\\n /**\\n * @notice Converts a given amount of shares to assets\\n * @param shares Number of shares to convert to assets\\n * @return Amount of assets for the given shares\\n */\\n function convertToAssets(UFixed18 shares) external view returns (UFixed18) {\\n (VersionContext memory context, ) = _loadContextForRead(address(0));\\n (context.latestCollateral, context.latestShares) =\\n (_totalAssetsAtVersion(context), _totalSupplyAtVersion(context));\\n return _convertToAssetsAtVersion(context, shares);\\n }\\n\\n /**\\n * @notice Hook that is called before every stateful operation\\n * @dev Settles the vault's account on both the long and short product, along with any global or user-specific deposits/redemptions\\n * @param account The account that called the operation, or 0 if called by a keeper.\\n * @return context The current version context\\n */\\n function _settle(address account) private returns (VersionContext memory context, VersionContext memory accountContext) {\\n (context, accountContext) = _loadContextForWrite(account);\\n\\n if (context.version > _latestVersion) {\\n _delayedMint(_totalSupplyAtVersion(context).sub(_totalSupply));\\n _totalUnclaimed = _totalUnclaimedAtVersion(context);\\n _deposit = UFixed18Lib.ZERO;\\n _redemption = UFixed18Lib.ZERO;\\n _latestVersion = context.version;\\n\\n _versions[context.version] = Version({\\n longPosition: long.position(address(this)).maker,\\n shortPosition: short.position(address(this)).maker,\\n totalShares: _totalSupply,\\n longAssets: collateral.collateral(address(this), long),\\n shortAssets: collateral.collateral(address(this), short),\\n totalAssets: _totalAssetsAtVersion(context)\\n });\\n }\\n\\n if (account != address(0) && accountContext.version > _latestVersions[account]) {\\n _delayedMintAccount(account, _balanceOfAtVersion(accountContext, account).sub(_balanceOf[account]));\\n _unclaimed[account] = _unclaimedAtVersion(accountContext, account);\\n _deposits[account] = UFixed18Lib.ZERO;\\n _redemptions[account] = UFixed18Lib.ZERO;\\n _latestVersions[account] = accountContext.version;\\n }\\n }\\n\\n /**\\n * @notice Rebalances the collateral and position of the vault\\n * @dev Rebalance is executed on best-effort, any failing legs of the strategy will not cause a revert\\n * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation\\n */\\n function _rebalance(VersionContext memory context, UFixed18 claimAmount) private {\\n _rebalanceCollateral(claimAmount);\\n _rebalancePosition(context, claimAmount);\\n }\\n\\n /**\\n * @notice Rebalances the collateral of the vault\\n * @param claimAmount The amount of assets that will be withdrawn from the vault at the end of the operation\\n */\\n function _rebalanceCollateral(UFixed18 claimAmount) private {\\n (UFixed18 longCollateral, UFixed18 shortCollateral, UFixed18 idleCollateral) = _collateral();\\n UFixed18 currentCollateral = longCollateral.add(shortCollateral).add(idleCollateral).sub(claimAmount);\\n UFixed18 targetCollateral = currentCollateral.div(TWO);\\n if (targetCollateral.lt(controller.minCollateral())) targetCollateral = UFixed18Lib.ZERO;\\n\\n (IProduct greaterProduct, IProduct lesserProduct) =\\n longCollateral.gt(shortCollateral) ? (long, short) : (short, long);\\n\\n _updateCollateral(greaterProduct, greaterProduct == long ? longCollateral : shortCollateral, targetCollateral);\\n _updateCollateral(lesserProduct, lesserProduct == long ? longCollateral : shortCollateral, targetCollateral);\\n }\\n\\n /**\\n * @notice Rebalances the position of the vault\\n */\\n function _rebalancePosition(VersionContext memory context, UFixed18 claimAmount) private {\\n UFixed18 currentAssets = _totalAssetsAtVersion(context).sub(claimAmount);\\n UFixed18 currentUtilized = _totalSupply.add(_redemption).isZero() ?\\n _deposit.add(currentAssets) :\\n _deposit.add(currentAssets.muldiv(_totalSupply, _totalSupply.add(_redemption)));\\n if (currentUtilized.lt(controller.minCollateral().mul(TWO))) currentUtilized = UFixed18Lib.ZERO;\\n\\n UFixed18 currentPrice = long.atVersion(context.version).price.abs();\\n UFixed18 targetPosition = currentUtilized.mul(targetLeverage).div(currentPrice).div(TWO);\\n\\n _updateMakerPosition(long, targetPosition);\\n _updateMakerPosition(short, targetPosition);\\n }\\n\\n /**\\n * @notice Adjusts the collateral on `product` to `targetCollateral`\\n * @param product The product to adjust the vault's collateral on\\n * @param currentCollateral The current collateral of the product\\n * @param targetCollateral The new collateral to target\\n */\\n function _updateCollateral(IProduct product, UFixed18 currentCollateral, UFixed18 targetCollateral) private {\\n if (currentCollateral.gt(targetCollateral))\\n collateral.withdrawTo(address(this), product, currentCollateral.sub(targetCollateral));\\n if (currentCollateral.lt(targetCollateral))\\n collateral.depositTo(address(this), product, targetCollateral.sub(currentCollateral));\\n\\n emit CollateralUpdated(product, targetCollateral);\\n }\\n\\n /**\\n * @notice Adjusts the position on `product` to `targetPosition`\\n * @param product The product to adjust the vault's position on\\n * @param targetPosition The new position to target\\n */\\n function _updateMakerPosition(IProduct product, UFixed18 targetPosition) private {\\n UFixed18 currentPosition = product.position(address(this)).next(product.pre(address(this))).maker;\\n UFixed18 currentMaker = product.positionAtVersion(product.latestVersion()).next(product.pre()).maker;\\n UFixed18 makerLimit = product.makerLimit();\\n UFixed18 makerAvailable = makerLimit.gt(currentMaker) ? makerLimit.sub(currentMaker) : UFixed18Lib.ZERO;\\n\\n if (targetPosition.lt(currentPosition))\\n product.closeMake(currentPosition.sub(targetPosition));\\n if (targetPosition.gte(currentPosition))\\n product.openMake(targetPosition.sub(currentPosition).min(makerAvailable));\\n\\n emit PositionUpdated(product, targetPosition);\\n }\\n\\n /**\\n * @notice Moves `amount` shares from `from` to `to`\\n * @param from Address to send shares from\\n * @param to Address to send shares to\\n * @param amount Amount of shares to move\\n */\\n function _transfer(address from, address to, UFixed18 amount) private {\\n _balanceOf[from] = _balanceOf[from].sub(amount);\\n _balanceOf[to] = _balanceOf[to].add(amount);\\n emit Transfer(from, to, amount);\\n }\\n\\n /**\\n * @notice Burns `amount` shares from `from`, adjusting totalSupply\\n * @param from Address to burn shares from\\n * @param amount Amount of shares to burn\\n */\\n function _burn(address from, UFixed18 amount) private {\\n _balanceOf[from] = _balanceOf[from].sub(amount);\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(from, address(0), amount);\\n }\\n\\n /**\\n * @notice Mints `amount` shares, adjusting totalSupply\\n * @param amount Amount of shares to mint\\n */\\n function _delayedMint(UFixed18 amount) private {\\n _totalSupply = _totalSupply.add(amount);\\n }\\n\\n /**\\n * @notice Mints `amount` shares to `to`\\n * @param to Address to mint shares to\\n * @param amount Amount of shares to mint\\n */\\n function _delayedMintAccount(address to, UFixed18 amount) private {\\n _balanceOf[to] = _balanceOf[to].add(amount);\\n emit Transfer(address(0), to, amount);\\n }\\n\\n /**\\n * @notice Decrements `spender`s allowance for `account` by `amount`\\n * @dev Does not decrement if approval is for -1\\n * @param account Address of allower\\n * @param spender Address of spender\\n * @param amount Amount to decrease allowance by\\n */\\n function _consumeAllowance(address account, address spender, UFixed18 amount) private {\\n if (allowance[account][spender].eq(UFixed18Lib.MAX)) return;\\n allowance[account][spender] = allowance[account][spender].sub(amount);\\n }\\n\\n /**\\n * @notice Loads the context for the given `account`, settling the vault first\\n * @param account Account to load the context for\\n * @return global version context\\n * @return account version context\\n */\\n function _loadContextForWrite(address account) private returns (VersionContext memory, VersionContext memory) {\\n long.settleAccount(address(this));\\n short.settleAccount(address(this));\\n uint256 currentVersion = long.latestVersion(address(this));\\n\\n return (\\n VersionContext(currentVersion, _assetsAt(_latestVersion), _sharesAt(_latestVersion)),\\n VersionContext(currentVersion, _assetsAt(_latestVersions[account]), _sharesAt(_latestVersions[account]))\\n );\\n }\\n\\n /**\\n * @notice Loads the context for the given `account`\\n * @param account Account to load the context for\\n * @return global version context\\n * @return account version context\\n */\\n function _loadContextForRead(address account) private view returns (VersionContext memory, VersionContext memory) {\\n uint256 currentVersion = Math.min(long.latestVersion(), short.latestVersion()); // latest version that both products are settled to\\n\\n return (\\n VersionContext(currentVersion, _assetsAt(_latestVersion), _sharesAt(_latestVersion)),\\n VersionContext(currentVersion, _assetsAt(_latestVersions[account]), _sharesAt(_latestVersions[account]))\\n );\\n }\\n\\n /**\\n * @notice Calculates whether or not the vault is in an unhealthy state at the provided version\\n * @param context Version context to calculate health\\n * @return bool true if unhealthy, false if healthy\\n */\\n function _unhealthyAtVersion(VersionContext memory context) private view returns (bool) {\\n return collateral.liquidatable(address(this), long)\\n || collateral.liquidatable(address(this), short)\\n || long.isLiquidating(address(this))\\n || short.isLiquidating(address(this))\\n || (!context.latestShares.isZero() && context.latestCollateral.isZero());\\n }\\n\\n /**\\n * @notice The maximum available deposit amount at the given version\\n * @param context Version context to use in calculation\\n * @return Maximum available deposit amount at version\\n */\\n function _maxDepositAtVersion(VersionContext memory context) private view returns (UFixed18) {\\n if (_unhealthyAtVersion(context)) return UFixed18Lib.ZERO;\\n UFixed18 currentCollateral = _totalAssetsAtVersion(context).add(_deposit);\\n return maxCollateral.gt(currentCollateral) ? maxCollateral.sub(currentCollateral) : UFixed18Lib.ZERO;\\n }\\n\\n /**\\n * @notice The maximum available redeemable amount at the given version for `account`\\n * @param context Version context to use in calculation\\n * @param accountContext Account version context to use in calculation\\n * @param account Account to calculate redeemable amount\\n * @return Maximum available redeemable amount at version\\n */\\n function _maxRedeemAtVersion(\\n VersionContext memory context,\\n VersionContext memory accountContext,\\n address account\\n ) private view returns (UFixed18) {\\n if (_unhealthyAtVersion(context)) return UFixed18Lib.ZERO;\\n return _balanceOfAtVersion(accountContext, account);\\n }\\n\\n /**\\n * @notice The total assets at the given version\\n * @param context Version context to use in calculation\\n * @return Total assets amount at version\\n */\\n function _totalAssetsAtVersion(VersionContext memory context) private view returns (UFixed18) {\\n (UFixed18 longCollateral, UFixed18 shortCollateral, UFixed18 idleCollateral) = _collateral();\\n (UFixed18 totalCollateral, UFixed18 totalDebt) =\\n (longCollateral.add(shortCollateral).add(idleCollateral), _totalUnclaimedAtVersion(context).add(_deposit));\\n return totalCollateral.gt(totalDebt) ? totalCollateral.sub(totalDebt) : UFixed18Lib.ZERO;\\n }\\n\\n /**\\n * @notice The total supply at the given version\\n * @param context Version context to use in calculation\\n * @return Total supply amount at version\\n */\\n function _totalSupplyAtVersion(VersionContext memory context) private view returns (UFixed18) {\\n if (context.version == _latestVersion) return _totalSupply;\\n return _totalSupply.add(_convertToSharesAtVersion(context, _deposit));\\n }\\n\\n /**\\n * @notice The balance of `account` at the given version\\n * @param accountContext Account version context to use in calculation\\n * @param account Account to calculate balance of amount\\n * @return Account balance at version\\n */\\n function _balanceOfAtVersion(VersionContext memory accountContext, address account) private view returns (UFixed18) {\\n if (accountContext.version == _latestVersions[account]) return _balanceOf[account];\\n return _balanceOf[account].add(_convertToSharesAtVersion(accountContext, _deposits[account]));\\n }\\n\\n /**\\n * @notice The total unclaimed assets at the given version\\n * @param context Version context to use in calculation\\n * @return Total unclaimed asset amount at version\\n */\\n function _totalUnclaimedAtVersion(VersionContext memory context) private view returns (UFixed18) {\\n if (context.version == _latestVersion) return _totalUnclaimed;\\n return _totalUnclaimed.add(_convertToAssetsAtVersion(context, _redemption));\\n }\\n\\n /**\\n * @notice The total unclaimed assets at the given version for `account`\\n * @param accountContext Account version context to use in calculation\\n * @param account Account to calculate unclaimed assets for\\n * @return Total unclaimed asset amount for `account` at version\\n */\\n function _unclaimedAtVersion(VersionContext memory accountContext, address account) private view returns (UFixed18) {\\n if (accountContext.version == _latestVersions[account]) return _unclaimed[account];\\n return _unclaimed[account].add(_convertToAssetsAtVersion(accountContext, _redemptions[account]));\\n }\\n\\n /**\\n * @notice Returns the amounts of the individual sources of assets in the vault\\n * @return The amount of collateral in the long product\\n * @return The amount of collateral in the short product\\n * @return The amount of collateral idle in the vault contract\\n */\\n function _collateral() private view returns (UFixed18, UFixed18, UFixed18) {\\n return (\\n collateral.collateral(address(this), long),\\n collateral.collateral(address(this), short),\\n asset.balanceOf()\\n );\\n }\\n\\n /**\\n * @notice The total assets at the given version\\n * @dev Calculates and adds accumulated PnL for `version` + 1\\n * @param version Version to get total assets at\\n * @return Total assets in the vault at the given version\\n */\\n function _assetsAt(uint256 version) private view returns (UFixed18) {\\n Fixed18 longAccumulated = long.valueAtVersion(version + 1).maker.sub(long.valueAtVersion(version).maker)\\n .mul(Fixed18Lib.from(_versions[version].longPosition))\\n .max(Fixed18Lib.from(_versions[version].longAssets).mul(Fixed18Lib.NEG_ONE)); // collateral can't go negative on a product\\n Fixed18 shortAccumulated = short.valueAtVersion(version + 1).maker.sub(short.valueAtVersion(version).maker)\\n .mul(Fixed18Lib.from(_versions[version].shortPosition))\\n .max(Fixed18Lib.from(_versions[version].shortAssets).mul(Fixed18Lib.NEG_ONE)); // collateral can't go negative on a product\\n\\n return UFixed18Lib.from(\\n Fixed18Lib.from(_versions[version].totalAssets)\\n .add(longAccumulated)\\n .add(shortAccumulated)\\n .max(Fixed18Lib.ZERO) // vault can't have negative assets, socializes into unclaimed if triggered\\n );\\n }\\n\\n /**\\n * @notice The total shares at the given version\\n * @param version Version to get total shares at\\n * @return Total shares at `version`\\n */\\n function _sharesAt(uint256 version) private view returns (UFixed18) {\\n return _versions[version].totalShares;\\n }\\n\\n /**\\n * @notice Converts a given amount of assets to shares at version\\n * @param context Version context to use in calculation\\n * @param assets Number of assets to convert to shares\\n * @return Amount of shares for the given assets at version\\n */\\n function _convertToSharesAtVersion(VersionContext memory context, UFixed18 assets) private pure returns (UFixed18) {\\n if (context.latestCollateral.isZero()) return assets;\\n return assets.muldiv(context.latestShares, context.latestCollateral);\\n }\\n\\n /**\\n * @notice Converts a given amount of shares to assets at version\\n * @param context Version context to use in calculation\\n * @param shares Number of shares to convert to shares\\n * @return Amount of assets for the given shares at version\\n */\\n function _convertToAssetsAtVersion(VersionContext memory context, UFixed18 shares) private pure returns (UFixed18) {\\n if (context.latestShares.isZero()) return shares;\\n return shares.muldiv(context.latestCollateral, context.latestShares);\\n }\\n}\\n\",\"keccak256\":\"0x6047bcda9488ec3fb223acd264c2108a7eb6cc85f0525ebaf0c46698602f96b2\",\"license\":\"Apache-2.0\"},\"contracts/interfaces/IBalancedVault.sol\":{\"content\":\"//SPDX-License-Identifier: Apache-2.0\\npragma solidity ^0.8.13;\\n\\nimport \\\"@equilibria/perennial/contracts/interfaces/IController.sol\\\";\\nimport \\\"@equilibria/perennial/contracts/interfaces/ICollateral.sol\\\";\\nimport \\\"@equilibria/root/number/types/UFixed18.sol\\\";\\n\\ninterface IBalancedVault {\\n\\n /* BalancedVault Interface */\\n\\n struct Version {\\n UFixed18 longPosition;\\n UFixed18 shortPosition;\\n UFixed18 totalShares;\\n UFixed18 longAssets;\\n UFixed18 shortAssets;\\n UFixed18 totalAssets;\\n }\\n\\n struct VersionContext {\\n uint256 version;\\n UFixed18 latestCollateral;\\n UFixed18 latestShares;\\n }\\n\\n event Deposit(address indexed sender, address indexed account, uint256 version, UFixed18 assets);\\n event Redemption(address indexed sender, address indexed account, uint256 version, UFixed18 shares);\\n event Claim(address indexed sender, address indexed account, UFixed18 assets);\\n event PositionUpdated(IProduct product, UFixed18 targetPosition);\\n event CollateralUpdated(IProduct product, UFixed18 targetCollateral);\\n\\n error BalancedVaultDepositLimitExceeded();\\n error BalancedVaultRedemptionLimitExceeded();\\n\\n function initialize(string memory name_, string memory symbol_) external;\\n function sync() external;\\n function controller() external view returns (IController);\\n function collateral() external view returns (ICollateral);\\n function long() external view returns (IProduct);\\n function short() external view returns (IProduct);\\n function targetLeverage() external view returns (UFixed18);\\n function maxCollateral() external view returns (UFixed18);\\n function unclaimed(address account) external view returns (UFixed18);\\n function totalUnclaimed() external view returns (UFixed18);\\n function claim(address account) external;\\n\\n /* Partial ERC4626 Interface */\\n\\n function asset() external view returns (Token18);\\n function totalAssets() external view returns (UFixed18);\\n function convertToShares(UFixed18 assets) external view returns (UFixed18);\\n function convertToAssets(UFixed18 shares) external view returns (UFixed18);\\n function maxDeposit(address account) external view returns (UFixed18);\\n function deposit(UFixed18 assets, address account) external;\\n function maxRedeem(address account) external view returns (UFixed18);\\n function redeem(UFixed18 shares, address account) external;\\n\\n /* Partial ERC20 Interface */\\n\\n event Transfer(address indexed from, address indexed to, UFixed18 value);\\n event Approval(address indexed account, address indexed spender, UFixed18 value);\\n\\n function name() external view returns (string memory);\\n function symbol() external view returns (string memory);\\n function decimals() external view returns (uint8);\\n function totalSupply() external view returns (UFixed18);\\n function balanceOf(address account) external view returns (UFixed18);\\n function transfer(address to, UFixed18 amount) external returns (bool);\\n function allowance(address account, address spender) external view returns (UFixed18);\\n function approve(address spender, UFixed18 amount) external returns (bool);\\n function transferFrom(address from, address to, UFixed18 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0xa6109b1eda80d9d323b3f80cb85daf93c9dfe4bd479ce76ae73842c4d58dcd1a\",\"license\":\"Apache-2.0\"}},\"version\":1}", "bytecode": "0x6101606040523480156200001257600080fd5b50604051620045cc380380620045cc8339810160408190526200003591620000f5565b6001600160a01b0380871661014052851660808190526040805163d8dfeb4560e01b8152905163d8dfeb45916004808201926020929091908290030181865afa15801562000087573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ad919062000171565b6001600160a01b0390811660a05293841660c0529190921660e052610100919091526101205250620001989050565b6001600160a01b0381168114620000f257600080fd5b50565b60008060008060008060c087890312156200010f57600080fd5b86516200011c81620000dc565b60208801519096506200012f81620000dc565b60408801519095506200014281620000dc565b60608801519094506200015581620000dc565b809350506080870151915060a087015190509295509295509295565b6000602082840312156200018457600080fd5b81516200019181620000dc565b9392505050565b60805160a05160c05160e051610100516101205161014051614297620003356000396000818161030d015281816107130152818161087601528181610a5f01526116b20152600081816102b00152818161195201526119870152600081816103dc01526127d80152600081816102e601528181610da6015281816111630152818161130f0152818161161a01528181611f6e01528181612005015281816121840152818161247f015281816124e70152818161283301528181612a6e0152612be901526000818161021101528181610d17015281816110ae015281816112340152818161153b01528181611d9301528181611e2a015281816120e701528181612227015281816124a0015281816124c6015281816125110152818161257601528181612737015281816128090152818161298d0152612b35015260008181610403015281816108980152818161125f0152818161133d0152818161156a01528181611642015281816129b801528181612a96015281816130230152613107015260008181610468015281816123cf015261266201526142976000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c8063505bd3da116100f9578063c96f14b811610097578063d905777e11610071578063d905777e14610425578063dd62ed3e14610438578063f77c479114610463578063fff6cae91461048a57600080fd5b8063c96f14b8146103cf578063d6c946ea146103d7578063d8dfeb45146103fe57600080fd5b80637bde82f2116100d35780637bde82f21461038e57806395d89b41146103a1578063a9059cbb146103a9578063c6e6f592146103bc57600080fd5b8063505bd3da146103555780636e553f651461036857806370a082311461037b57600080fd5b806323b872dd1161016657806338bea4cb1161014057806338bea4cb146102e157806338d52e0f14610308578063402d267d1461032f5780634cd88b761461034257600080fd5b806323b872dd14610298578063251f47c1146102ab578063313ce567146102d257600080fd5b806307bfce37116101a257806307bfce371461020c578063095ea7b31461025857806318160ddd1461027b5780631e83409a1461028357600080fd5b806301e1d114146101c957806306fdde03146101e457806307a2d13a146101f9575b600080fd5b6101d1610492565b6040519081526020015b60405180910390f35b6101ec6104b1565b6040516101db9190613acf565b6101d1610207366004613b20565b61053f565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101db565b61026b610266366004613b62565b61057c565b60405190151581526020016101db565b6101d16105f6565b610296610291366004613b8c565b61060f565b005b61026b6102a6366004613ba7565b610745565b6101d17f000000000000000000000000000000000000000000000000000000000000000081565b604051601281526020016101db565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b6101d161033d366004613b8c565b610772565b610296610350366004613cbd565b61078b565b6101d1610363366004613b8c565b610919565b610296610376366004613d21565b610932565b6101d1610389366004613b8c565b610a96565b61029661039c366004613d21565b610aaf565b6101ec610c09565b61026b6103b7366004613b62565b610c16565b6101d16103ca366004613b20565b610c37565b6101d1610c6d565b6101d17f000000000000000000000000000000000000000000000000000000000000000081565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b6101d1610433366004613b8c565b610c86565b6101d1610446366004613d4d565b600260209081526000928352604080842090915290825290205481565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b610296610cab565b60008061049f6000610cc8565b5090506104ab81610f19565b91505090565b600080546104be90613d77565b80601f01602080910402602001604051908101604052809291908181526020018280546104ea90613d77565b80156105375780601f1061050c57610100808354040283529160200191610537565b820191906000526020600020905b81548152906001019060200180831161051a57829003601f168201915b505050505081565b60008061054c6000610cc8565b50905061055881610f19565b61056182610f7d565b604083015260208201526105758184610fac565b9392505050565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105e49086815260200190565b60405180910390a35060015b92915050565b6000806106036000610cc8565b5090506104ab81610f7d565b600061061a82610fdb565b5073ffffffffffffffffffffffffffffffffffffffff8316600090815260056020526040812080546006549290915591925061065681836114ec565b60065560405182815273ffffffffffffffffffffffffffffffffffffffff85169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a381600080806106b36114f8565b9194509250905060006106d0826106ca86866116f7565b906116f7565b90506106dc8187611703565b156106ef576106ec858288611717565b94505b6106f9888661172e565b61073a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a87611745565b505050505050505050565b600061075084610fdb565b505061075d843384611766565b610768848484611848565b5060019392505050565b60008061077f6000610cc8565b50905061057581611922565b6001806107b67f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b5490565b106107f5576040517f1e7a9d95000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b61081e7f5db5abc19987c2b3729df7961b62b6bb0bae886dd47e3ce25bb3a3af34c6d80b829055565b60017fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c55600061084e8482613e10565b50600161085b8382613e10565b506108bc73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006119ac565b60007fad57d7911b7e3d6c3c79a68ba909a7f4ba41f9485e5207b12dee0d0c6af5398c556040518181527fbe9b076dc5b65990cca9dd9d7366682482e7817a6f6bc7f4faf4dc32af497f32906020015b60405180910390a1505050565b60008061092583610cc8565b91505061057581846119ed565b600061093d82610fdb565b50905061095361094c82611922565b8490611aa7565b1561098a576040517f6726139b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075461099790846116f7565b600755805160095573ffffffffffffffffffffffffffffffffffffffff82166000908152600a60205260409020546109cf90846116f7565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600a60209081526040808320949094558451600c8252918490209190915583518351908152908101869052909133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610a8673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163385611abd565b610a9181600061172e565b505050565b600080610aa283610cc8565b9150506105758184611adf565b3373ffffffffffffffffffffffffffffffffffffffff821614610ad757610ad7813384611766565b600080610ae383610fdb565b91509150610afc610af5838386611b99565b8590611aa7565b15610b33576040517f457c19da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854610b4090856116f7565b600855815160095573ffffffffffffffffffffffffffffffffffffffff83166000908152600b6020526040902054610b7890856116f7565b73ffffffffffffffffffffffffffffffffffffffff84166000818152600b60209081526040808320949094558551600c8252918490209190915584518351908152908101879052909133917fa28d80c9910787c0c058ed9b50c577f1389264bf61563fa45529e0771976f562910160405180910390a3610bf88385611bbb565b610c0382600061172e565b50505050565b600180546104be90613d77565b6000610c2133610fdb565b5050610c2e338484611848565b50600192915050565b600080610c446000610cc8565b509050610c5081610f19565b610c5982610f7d565b604083015260208201526105758184611c74565b600080610c7a6000610cc8565b5090506104ab81611ca3565b6000806000610c9484610cc8565b91509150610ca3828286611b99565b949350505050565b6000610cb76000610fdb565b509050610cc581600061172e565b50565b610cec60405180606001604052806000815260200160008152602001600081525090565b610d1060405180606001604052806000815260200160008152602001600081525090565b6000610e387f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da49190613f2a565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190613f2a565b611cd2565b90506040518060600160405280828152602001610e56600954611ce8565b8152602001610e766009546000908152600d602052604090206002015490565b8152506040518060600160405280838152602001610ed2600c60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611ce8565b815273ffffffffffffffffffffffffffffffffffffffff969096166000908152600c60209081526040808320548352600d8252909120600201549601959095529492505050565b600080600080610f276114f8565b91945092509050600080610f3f836106ca87876116f7565b610f4e6007546106ca8a611ca3565b9092509050610f5d8282611aa7565b610f68576000610f72565b610f7282826114ec565b979650505050505050565b6000600954826000015103610f9457505060045490565b6105f0610fa383600754611c74565b600454906116f7565b6000610fba83604001511590565b15610fc65750806105f0565b60208301516040840151610575918491611717565b610fff60405180606001604052806000815260200160008152602001600081525090565b61102360405180606001604052806000815260200160008152602001600081525090565b61102c83612071565b600954825192945090925010156114035761105a61105560045461104f85610f7d565b906114ec565b6122a8565b61106382611ca3565b6006556000600781905560085581516009556040805160c08101918290527fb7648fb9000000000000000000000000000000000000000000000000000000009091523060c4820152807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b7648fb960e483016040805180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613f92565b5181526040517fb7648fb90000000000000000000000000000000000000000000000000000000081523060048201526020909101907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063b7648fb9906024016040805180830381865afa1580156111be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e29190613f92565b518152600480546020830152604080517fcc218ece000000000000000000000000000000000000000000000000000000008152309281019290925273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248401529201917f0000000000000000000000000000000000000000000000000000000000000000169063cc218ece90604401602060405180830381865afa1580156112a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ca9190613f2a565b81526040517fcc218ece00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301526020909201917f0000000000000000000000000000000000000000000000000000000000000000169063cc218ece90604401602060405180830381865afa158015611384573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a89190613f2a565b81526020016113b684610f19565b905282516000908152600d602090815260409182902083518155908301516001820155908201516002820155606082015160038201556080820151600482015560a0909101516005909101555b73ffffffffffffffffffffffffffffffffffffffff83161580159061144d575073ffffffffffffffffffffffffffffffffffffffff83166000908152600c60205260409020548151115b156114e75773ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604090205461149190849061148c9061104f8584611adf565b6122bb565b61149b81846119ed565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260056020908152604080832093909355600a8152828220829055600b81528282208290558351600c909152919020555b915091565b60006105758284613fdd565b6040517fcc218ece00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166024830152600091829182917f00000000000000000000000000000000000000000000000000000000000000009091169063cc218ece90604401602060405180830381865afa1580156115b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d79190613f2a565b6040517fcc218ece00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063cc218ece90604401602060405180830381865afa158015611689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ad9190613f2a565b6116ec7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16612349565b925092509250909192565b60006105758284613ff0565b600061170f8383612355565b159392505050565b6000816117248486614003565b610ca39190614049565b6117378161238a565b61174182826125d7565b5050565b610a9173ffffffffffffffffffffffffffffffffffffffff84168383612860565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260209081526040808320938616835292905220546117c3907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612934565b156117cd57505050565b73ffffffffffffffffffffffffffffffffffffffff80841660009081526002602090815260408083209386168352929052205461180a90826114ec565b73ffffffffffffffffffffffffffffffffffffffff938416600090815260026020908152604080832095909616825293909352929091209190915550565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604090205461187890826114ec565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526003602052604080822093909355908416815220546118b490826116f7565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526003602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906119159085815260200190565b60405180910390a3505050565b600061192d8261294a565b1561193a57506000919050565b600061194b6007546106ca85610f19565b90506119777f000000000000000000000000000000000000000000000000000000000000000082611aa7565b611982576000610575565b6105757f0000000000000000000000000000000000000000000000000000000000000000826114ec565b61174173ffffffffffffffffffffffffffffffffffffffff8316827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612c88565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020526040812054835103611a46575073ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260409020546105f0565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604090205461057590611a7b908590610fac565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260056020526040902054906116f7565b6000611ab38383612355565b6002149392505050565b610a9173ffffffffffffffffffffffffffffffffffffffff8416833084612e0a565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020526040812054835103611b38575073ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020546105f0565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600a602052604090205461057590611b6d908590611c74565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054906116f7565b6000611ba48461294a565b15611bb157506000610575565b610ca38383611adf565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040902054611beb90826114ec565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040902055600454611c1e90826114ec565b60045560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000611c8283602001511590565b15611c8e5750806105f0565b60408301516020840151610575918491611717565b6000600954826000015103611cba57505060065490565b6105f0611cc983600854610fac565b600654906116f7565b6000818310611ce15781610575565b5090919050565b600080611ec5611d44611d23670de0b6b3a76400007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61405d565b6000868152600d6020526040902060030154611d3e90612e68565b90612ec7565b6000858152600d6020526040902054611ebf90611d6090612e68565b6040517f20fe9c3c00000000000000000000000000000000000000000000000000000000815260048101889052611d3e907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906320fe9c3c906024016040805180830381865afa158015611dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e129190613f43565b5173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166320fe9c3c611e5a8b6001613ff0565b6040518263ffffffff1660e01b8152600401611e7891815260200190565b6040805180830381865afa158015611e94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb89190613f43565b5190612ee6565b90612ef2565b90506000612035611f1c611f01670de0b6b3a76400007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61405d565b6000878152600d6020526040902060040154611d3e90612e68565b6000868152600d6020526040902060010154611ebf90611f3b90612e68565b6040517f20fe9c3c00000000000000000000000000000000000000000000000000000000815260048101899052611d3e907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906320fe9c3c906024016040805180830381865afa158015611fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fed9190613f43565b5173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166320fe9c3c611e5a8c6001613ff0565b9050610ca361206c6000611ebf8461206687612066600d60008d815260200190815260200160002060050154612e68565b90612efe565b612f0a565b61209560405180606001604052806000815260200160008152602001600081525090565b6120b960405180606001604052806000815260200160008152602001600081525090565b6040517ff667f8970000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063f667f89790602401600060405180830381600087803b15801561214057600080fd5b505af1158015612154573d6000803e3d6000fd5b50506040517ff667f8970000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16925063f667f8979150602401600060405180830381600087803b1580156121df57600080fd5b505af11580156121f3573d6000803e3d6000fd5b50506040517f8e480b20000000000000000000000000000000000000000000000000000000008152306004820152600092507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169150638e480b2090602401602060405180830381865afa158015612284573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e389190613f2a565b6004546122b590826116f7565b60045550565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020546122eb90826116f7565b73ffffffffffffffffffffffffffffffffffffffff83166000818152600360205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611c689085815260200190565b60006105f08230612f4a565b600082828082111561236c576002925050506105f0565b8082101561237f576000925050506105f0565b506001949350505050565b60008060006123976114f8565b9194509250905060006123b28561104f846106ca88886116f7565b905060006123c882671bc16d674ec80000612fde565b90506124637f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ba2de9bc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245c9190613f2a565b8290611703565b1561246c575060005b6000806124798787611aa7565b6124c4577f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612507565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005b91509150612570827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612568578761256a565b885b85612ffd565b6125cd817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612568578761256a565b5050505050505050565b60006125e68261104f85610f19565b905060006126086126046008546004546116f790919063ffffffff16565b1590565b6126425761263d61263460045461262c6008546004546116f790919063ffffffff16565b859190611717565b600754906116f7565b61264f565b60075461264f90836116f7565b90506126f561245c671bc16d674ec800007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ba2de9bc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ef9190613f2a565b90613211565b156126fe575060005b83516040517f7ece075d00000000000000000000000000000000000000000000000000000000815260048101919091526000906127c0907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690637ece075d90602401606060405180830381865afa158015612793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127b791906140a9565b60400151613226565b90506000612802671bc16d674ec800006127fc8481877f0000000000000000000000000000000000000000000000000000000000000000613211565b90612fde565b905061282e7f000000000000000000000000000000000000000000000000000000000000000082613231565b6128587f000000000000000000000000000000000000000000000000000000000000000082613231565b505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a919084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613686565b60006129408383612355565b6001149392505050565b6040517f82df39de00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906382df39de90604401602060405180830381865afa158015612a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a259190614105565b80612b0157506040517f82df39de00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301527f000000000000000000000000000000000000000000000000000000000000000016906382df39de90604401602060405180830381865afa158015612add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b019190614105565b80612bb557506040517f58ca6f980000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906358ca6f9890602401602060405180830381865afa158015612b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb59190614105565b80612c6957506040517f58ca6f980000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906358ca6f9890602401602060405180830381865afa158015612c45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c699190614105565b806105f057506040820151151580156105f057506020820151156105f0565b801580612d2857506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612d02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d269190613f2a565b155b612db4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016107ec565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610a919084907f095ea7b300000000000000000000000000000000000000000000000000000000906064016128b2565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610c039085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016128b2565b6000817f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111156105f0576040517ea07eb5000000000000000000000000000000000000000000000000000000008152600481018290526024016107ec565b6000670de0b6b3a7640000612edc838561405d565b6105759190614127565b6000610575828461418f565b60006105758383613792565b600061057582846141b6565b600081818112156105f0576040517f501f289e000000000000000000000000000000000000000000000000000000008152600481018290526024016107ec565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152600091908416906370a0823190602401602060405180830381865afa158015612fba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105759190613f2a565b600081612ff3670de0b6b3a764000085614003565b6105759190614049565b6130078282611aa7565b156130e15773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663c3b35a7e308561305486866114ec565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529290911660248301526044820152606401600060405180830381600087803b1580156130c857600080fd5b505af11580156130dc573d6000803e3d6000fd5b505050505b6130eb8282611703565b156131c55773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663f213159c308561313885876114ec565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff93841660048201529290911660248301526044820152606401600060405180830381600087803b1580156131ac57600080fd5b505af11580156131c0573d6000803e3d6000fd5b505050505b6040805173ffffffffffffffffffffffffffffffffffffffff85168152602081018390527fdf43c689abc8d83e86b74634bbe0ba590e2ecb34f3f432a612c6edef3e532cbd910161090c565b6000670de0b6b3a7640000612ff38385614003565b60006105f0826137a1565b6040517f1e0c6fb900000000000000000000000000000000000000000000000000000000815230600482015260009061335a9073ffffffffffffffffffffffffffffffffffffffff851690631e0c6fb99060240160a060405180830381865afa1580156132a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c691906141de565b6040517fb7648fb900000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff86169063b7648fb9906024015b6040805180830381865afa158015613330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133549190613f92565b906137b8565b600001519050600061347d8473ffffffffffffffffffffffffffffffffffffffff166359ea287d6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156133b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d491906141de565b8573ffffffffffffffffffffffffffffffffffffffff16639a427d038773ffffffffffffffffffffffffffffffffffffffff1663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561343b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345f9190613f2a565b6040518263ffffffff1660e01b815260040161331491815260200190565b60000151905060008473ffffffffffffffffffffffffffffffffffffffff1663193775676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f49190613f2a565b905060006135028284611aa7565b61350d576000613517565b61351782846114ec565b90506135238585611703565b1561359f5773ffffffffffffffffffffffffffffffffffffffff86166359218fe961354e86886114ec565b6040518263ffffffff1660e01b815260040161356c91815260200190565b600060405180830381600087803b15801561358657600080fd5b505af115801561359a573d6000803e3d6000fd5b505050505b6135a985856137e7565b1561362f5773ffffffffffffffffffffffffffffffffffffffff861663d7d7d6b86135de836135d889896114ec565b90613803565b6040518263ffffffff1660e01b81526004016135fc91815260200190565b600060405180830381600087803b15801561361657600080fd5b505af115801561362a573d6000803e3d6000fd5b505050505b6040805173ffffffffffffffffffffffffffffffffffffffff88168152602081018790527f814d2340073b1f05a68bb3f6aab82bfc4eea78f35f7c2332caddf0c35865331e910160405180910390a1505050505050565b60006136e8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661380f9092919063ffffffff16565b805190915015610a9157808060200190518101906137069190614105565b610a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107ec565b6000818313611ce15781610575565b6000808212156137b457816000036105f0565b5090565b60408051808201909152600080825260208201526105756137dd84846020015161381e565b8360400151613875565b60006137f38383611aa7565b8061057557506105758383612934565b60006105758383611cd2565b6060610ca384846000856138c3565b60408051808201909152600080825260208201526040805180820190915282518451829161384c91906116f7565b815260200161386c846020015186602001516116f790919063ffffffff16565b90529392505050565b6040805180820190915260008082526020820152604080518082019091528251845182916138a391906114ec565b815260200161386c846020015186602001516114ec90919063ffffffff16565b606082471015613955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107ec565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161397e9190614245565b60006040518083038185875af1925050503d80600081146139bb576040519150601f19603f3d011682016040523d82523d6000602084013e6139c0565b606091505b5091509150610f728783838760608315613a62578251600003613a5b5773ffffffffffffffffffffffffffffffffffffffff85163b613a5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107ec565b5081610ca3565b610ca38383815115613a775781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ec9190613acf565b60005b83811015613ac6578181015183820152602001613aae565b50506000910152565b6020815260008251806020840152613aee816040850160208701613aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215613b3257600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114613b5d57600080fd5b919050565b60008060408385031215613b7557600080fd5b613b7e83613b39565b946020939093013593505050565b600060208284031215613b9e57600080fd5b61057582613b39565b600080600060608486031215613bbc57600080fd5b613bc584613b39565b9250613bd360208501613b39565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613c2357600080fd5b813567ffffffffffffffff80821115613c3e57613c3e613be3565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613c8457613c84613be3565b81604052838152866020858801011115613c9d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215613cd057600080fd5b823567ffffffffffffffff80821115613ce857600080fd5b613cf486838701613c12565b93506020850135915080821115613d0a57600080fd5b50613d1785828601613c12565b9150509250929050565b60008060408385031215613d3457600080fd5b82359150613d4460208401613b39565b90509250929050565b60008060408385031215613d6057600080fd5b613d6983613b39565b9150613d4460208401613b39565b600181811c90821680613d8b57607f821691505b602082108103613dc4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610a9157600081815260208120601f850160051c81016020861015613df15750805b601f850160051c820191505b8181101561285857828155600101613dfd565b815167ffffffffffffffff811115613e2a57613e2a613be3565b613e3e81613e388454613d77565b84613dca565b602080601f831160018114613e915760008415613e5b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612858565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613ede57888601518255948401946001909101908401613ebf565b5085821015613f1a57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215613f3c57600080fd5b5051919050565b600060408284031215613f5557600080fd5b6040516040810181811067ffffffffffffffff82111715613f7857613f78613be3565b604052825181526020928301519281019290925250919050565b600060408284031215613fa457600080fd5b6105758383613f43565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f0576105f0613fae565b808201808211156105f0576105f0613fae565b80820281158282048414176105f0576105f0613fae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826140585761405861401a565b500490565b808202600082127f80000000000000000000000000000000000000000000000000000000000000008414161561409557614095613fae565b81810583148215176105f0576105f0613fae565b6000606082840312156140bb57600080fd5b6040516060810181811067ffffffffffffffff821117156140de576140de613be3565b80604052508251815260208301516020820152604083015160408201528091505092915050565b60006020828403121561411757600080fd5b8151801515811461057557600080fd5b6000826141365761413661401a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561418a5761418a613fae565b500590565b81810360008312801583831316838312821617156141af576141af613fae565b5092915050565b80820182811260008312801582168215821617156141d6576141d6613fae565b505092915050565b600060a082840312156141f057600080fd5b6040516060810181811067ffffffffffffffff8211171561421357614213613be3565b604052825181526142278460208501613f43565b60208201526142398460608501613f43565b60408201529392505050565b60008251614257818460208701613aab565b919091019291505056fea26469706673582212209d02b13945e8d251b5265a6bd1a9b0021eb5f0b60d146b2025906d0f7c29f68164736f6c63430008110033",