diff --git a/contracts/deploy/091_simplified_oeth_vault.js b/contracts/deploy/091_simplified_oeth_vault.js index acef436779..e109e78525 100644 --- a/contracts/deploy/091_simplified_oeth_vault.js +++ b/contracts/deploy/091_simplified_oeth_vault.js @@ -11,7 +11,8 @@ module.exports = deploymentWithGovernanceProposal( // forceSkip: true, // onlyOnFork: true, // this is only executed in forked environment reduceQueueTime: true, // just to solve the issue of later active proposals failing - proposalId: "", + proposalId: + "78389253671544237322939434422056971914944279457140328550595948923573494383344", }, async ({ ethers }) => { const cOETHVaultProxy = await ethers.getContract("OETHVaultProxy"); @@ -28,7 +29,7 @@ module.exports = deploymentWithGovernanceProposal( return { name: "Simplified OETH mint and redeem\n\ \n\ - Part of simplified OETH proposal. Trims down mint and redeem complexity on OETH Vault. Set redeem fees to zero. \ + Part of simplified OETH proposal. Makes redeem WETH-only (no more LST-mix redeem). \ ", actions: [ { diff --git a/contracts/deployments/mainnet/.migrations.json b/contracts/deployments/mainnet/.migrations.json index 6a34a27672..c36aaba57e 100644 --- a/contracts/deployments/mainnet/.migrations.json +++ b/contracts/deployments/mainnet/.migrations.json @@ -81,5 +81,6 @@ "087_reduce_redeem_fee": 1710470610, "089_1inch_buyback": 1711371391, "090_disable_compound": 1711469659, + "091_simplified_oeth_vault": 1714138519, "092_woeth_ccip_zapper": 1714111493 -} \ No newline at end of file +} diff --git a/contracts/deployments/mainnet/OETHVaultCore.json b/contracts/deployments/mainnet/OETHVaultCore.json index 11b8825b17..5a116792c1 100644 --- a/contracts/deployments/mainnet/OETHVaultCore.json +++ b/contracts/deployments/mainnet/OETHVaultCore.json @@ -1,5 +1,5 @@ { - "address": "0x9535413B1B9862D0123A36F55e9bf20EBA4b152e", + "address": "0x8f371d8e65F35914CDb8Dd58B997411871dABb37", "abi": [ { "inputs": [ @@ -495,6 +495,13 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "cacheWETHAssetIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1028,47 +1035,60 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [], + "name": "wethAssetIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" } ], - "transactionHash": "0xba80bf4108a946f91c652af8183decaa94bec46e7de7867cd4d251a6ba6aed6e", + "transactionHash": "0x93bf00ade368876419f5310739d0b9648e9e161c78b77e8a720650d960daa82f", "receipt": { "to": null, "from": "0x58890A9cB27586E83Cb51d2d26bbE18a1a647245", - "contractAddress": "0x9535413B1B9862D0123A36F55e9bf20EBA4b152e", - "transactionIndex": 0, - "gasUsed": "3112674", - "logsBloom": "0x00000000000001000000000000000000004000000000000000000000000000000000000000000000000000000000000000008000000000000080000000000000000000001000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000008000000000000010000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x51057e91c0a6c74a1c66a71c662d8f696b2fbd4dc3bc20a0ebb09daaf19e5032", - "transactionHash": "0xba80bf4108a946f91c652af8183decaa94bec46e7de7867cd4d251a6ba6aed6e", + "contractAddress": "0x8f371d8e65F35914CDb8Dd58B997411871dABb37", + "transactionIndex": 4, + "gasUsed": "3024025", + "logsBloom": "0x00000000004001000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000004000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000010000000000000000000000000020000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x5760b877a2e8b7f59d55ce3e1dd8d516701cda8eac1d7deefb43977836bbab0d", + "transactionHash": "0x93bf00ade368876419f5310739d0b9648e9e161c78b77e8a720650d960daa82f", "logs": [ { - "transactionIndex": 0, - "blockNumber": 19384901, - "transactionHash": "0xba80bf4108a946f91c652af8183decaa94bec46e7de7867cd4d251a6ba6aed6e", - "address": "0x9535413B1B9862D0123A36F55e9bf20EBA4b152e", + "transactionIndex": 4, + "blockNumber": 19739861, + "transactionHash": "0x93bf00ade368876419f5310739d0b9648e9e161c78b77e8a720650d960daa82f", + "address": "0x8f371d8e65F35914CDb8Dd58B997411871dABb37", "topics": [ "0xc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000058890a9cb27586e83cb51d2d26bbe18a1a647245" ], "data": "0x", - "logIndex": 0, - "blockHash": "0x51057e91c0a6c74a1c66a71c662d8f696b2fbd4dc3bc20a0ebb09daaf19e5032" + "logIndex": 42, + "blockHash": "0x5760b877a2e8b7f59d55ce3e1dd8d516701cda8eac1d7deefb43977836bbab0d" } ], - "blockNumber": 19384901, - "cumulativeGasUsed": "3112674", + "blockNumber": 19739861, + "cumulativeGasUsed": "4157668", "status": 1, "byzantium": true }, "args": [ "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" ], - "numDeployments": 3, - "solcInputHash": "6fcb63b8cee774c2d77d3940339c008c", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"AllocateThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"AssetAllocated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"}],\"name\":\"AssetDefaultStrategyUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"AssetSupported\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"GovernorshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupplyDiff\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyDiffChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"NetOusdMintForStrategyThresholdChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ousdMetaStrategy\",\"type\":\"address\"}],\"name\":\"OusdMetaStrategyUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorshipTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_priceProvider\",\"type\":\"address\"}],\"name\":\"PriceProviderUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebasePaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"RebaseThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebaseUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Redeem\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_redeemFeeBps\",\"type\":\"uint256\"}],\"name\":\"RedeemFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"StrategistUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"StrategyApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"StrategyRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"SwapAllowedUndervalueChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"SwapSlippageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromAsset\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toAsset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fromAssetAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_toAssetAmount\",\"type\":\"uint256\"}],\"name\":\"Swapped\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"SwapperChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"TrusteeAddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"TrusteeFeeBpsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vaultBuffer\",\"type\":\"uint256\"}],\"name\":\"VaultBufferUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_yield\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"YieldDistribution\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"allocate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetDefaultStrategies\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"autoAllocateThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burnForStrategy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedeemOutputs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"capitalPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"checkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAssets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllStrategies\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"getAssetConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"},{\"internalType\":\"enum VaultStorage.UnitConversion\",\"name\":\"unitConversion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"allowedOracleSlippageBps\",\"type\":\"uint16\"}],\"internalType\":\"struct VaultStorage.Asset\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAssetCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStrategyCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_priceProvider\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oToken\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isGovernor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"isSupportedAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupplyDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mintForStrategy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"netOusdMintForStrategyThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"netOusdMintedForStrategy\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ousdMetaStrategy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"priceProvider\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"priceUnitMint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"priceUnitRedeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebase\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebasePaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebaseThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeemAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redeemFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImpl\",\"type\":\"address\"}],\"name\":\"setAdminImpl\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"strategistAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"transferGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trusteeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trusteeFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vaultBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"weth\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Origin Protocol Inc\",\"kind\":\"dev\",\"methods\":{\"burnForStrategy(uint256)\":{\"details\":\"Notice: can't use `nonReentrant` modifier since the `redeem` function could require withdrawal on `ConvexOUSDMetaStrategy` and that one can call `burnForStrategy` while the execution of the `redeem` has not yet completed -> causing a `nonReentrant` collision. Also important to understand is that this is a limitation imposed by the test suite. Production / mainnet contracts should never be configured in a way where mint/redeem functions that are moving funds between the Vault and end user wallets can influence strategies utilizing this function.\",\"params\":{\"_amount\":\"Amount of OUSD to burn\"}},\"checkBalance(address)\":{\"params\":{\"_asset\":\"Address of asset\"},\"returns\":{\"_0\":\"uint256 Balance of asset in decimals of asset\"}},\"isSupportedAsset(address)\":{\"params\":{\"_asset\":\"address of the asset\"},\"returns\":{\"_0\":\"true if supported\"}},\"mint(address,uint256,uint256)\":{\"params\":{\"_amount\":\"Amount of the asset being deposited\",\"_asset\":\"Address of the asset being deposited\",\"_minimumOusdAmount\":\"Minimum OTokens to mint\"}},\"mintForStrategy(uint256)\":{\"params\":{\"_amount\":\"Amount of the asset being deposited Notice: can't use `nonReentrant` modifier since the `mint` function can call `allocate`, and that can trigger `ConvexOUSDMetaStrategy` to call this function while the execution of the `mint` has not yet completed -> causing a `nonReentrant` collision. Also important to understand is that this is a limitation imposed by the test suite. Production / mainnet contracts should never be configured in a way where mint/redeem functions that are moving funds between the Vault and end user wallets can influence strategies utilizing this function.\"}},\"priceUnitMint(address)\":{\"params\":{\"asset\":\"address of the asset\"},\"returns\":{\"price\":\"uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\"}},\"priceUnitRedeem(address)\":{\"params\":{\"asset\":\"Address of the asset\"},\"returns\":{\"price\":\"uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\"}},\"redeem(uint256,uint256)\":{\"params\":{\"_amount\":\"Amount of OTokens to burn\",\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"redeemAll(uint256)\":{\"params\":{\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"setAdminImpl(address)\":{\"params\":{\"newImpl\":\"address of the implementation\"}},\"totalValue()\":{\"returns\":{\"value\":\"Total value in USD/ETH (1e18)\"}},\"transferGovernance(address)\":{\"params\":{\"_newGovernor\":\"Address of the new Governor\"}}},\"title\":\"OETH VaultCore Contract\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"allocate()\":{\"notice\":\"Allocate unallocated funds on Vault to strategies.*\"},\"assetDefaultStrategies(address)\":{\"notice\":\"Mapping of asset address to the Strategy that they should automatically\"},\"autoAllocateThreshold()\":{\"notice\":\"OToken mints over this amount automatically allocate funds. 18 decimals.\"},\"burnForStrategy(uint256)\":{\"notice\":\"Burn OTokens for Metapool Strategy\"},\"calculateRedeemOutputs(uint256)\":{\"notice\":\"Calculate the outputs for a redeem function, i.e. the mix of coins that will be returned\"},\"capitalPaused()\":{\"notice\":\"pause operations that change the OToken supply. eg mint, redeem, allocate, mint/burn for strategy\"},\"checkBalance(address)\":{\"notice\":\"Get the balance of an asset held in Vault and all strategies.\"},\"claimGovernance()\":{\"notice\":\"Claim Governance of the contract to a new account (`newGovernor`). Can only be called by the new Governor.\"},\"getAllAssets()\":{\"notice\":\"Return all vault asset addresses in order\"},\"getAllStrategies()\":{\"notice\":\"Return the array of all strategies\"},\"getAssetConfig(address)\":{\"notice\":\"Gets the vault configuration of a supported asset.\"},\"getAssetCount()\":{\"notice\":\"Return the number of assets supported by the Vault.\"},\"getStrategyCount()\":{\"notice\":\"Return the number of strategies active on the Vault.\"},\"governor()\":{\"notice\":\"Returns the address of the current Governor.\"},\"isGovernor()\":{\"notice\":\"Returns true if the caller is the current Governor.\"},\"isSupportedAsset(address)\":{\"notice\":\"Returns whether the vault supports the asset\"},\"maxSupplyDiff()\":{\"notice\":\"Max difference between total supply and total value of assets. 18 decimals.\"},\"mint(address,uint256,uint256)\":{\"notice\":\"Deposit a supported asset and mint OTokens.\"},\"mintForStrategy(uint256)\":{\"notice\":\"Mint OTokens for a Metapool Strategy\"},\"netOusdMintForStrategyThreshold()\":{\"notice\":\"How much net total OTokens are allowed to be minted by all strategies\"},\"netOusdMintedForStrategy()\":{\"notice\":\"How much OTokens are currently minted by the strategy\"},\"ousdMetaStrategy()\":{\"notice\":\"Metapool strategy that is allowed to mint/burn OTokens without changing collateral\"},\"priceProvider()\":{\"notice\":\"Address of the Oracle price provider contract\"},\"priceUnitMint(address)\":{\"notice\":\"Returns the total price in 18 digit units for a given asset. Never goes above 1, since that is how we price mints.\"},\"priceUnitRedeem(address)\":{\"notice\":\"Returns the total price in 18 digit unit for a given asset. Never goes below 1, since that is how we price redeems\"},\"rebase()\":{\"notice\":\"Calculate the total value of assets held by the Vault and all strategies and update the supply of OTokens.\"},\"rebasePaused()\":{\"notice\":\"pause rebasing if true\"},\"rebaseThreshold()\":{\"notice\":\"OToken mints over this amount automatically rebase. 18 decimals.\"},\"redeem(uint256,uint256)\":{\"notice\":\"Withdraw a supported asset and burn OTokens.\"},\"redeemAll(uint256)\":{\"notice\":\"Withdraw a supported asset and burn all OTokens.\"},\"redeemFeeBps()\":{\"notice\":\"Redemption fee in basis points. eg 50 = 0.5%\"},\"setAdminImpl(address)\":{\"notice\":\"set the implementation for the admin, this needs to be in a base class else we cannot set it\"},\"strategistAddr()\":{\"notice\":\"Address of the Strategist\"},\"totalValue()\":{\"notice\":\"Determine the total value of assets held by the vault and its strategies.\"},\"transferGovernance(address)\":{\"notice\":\"Transfers Governance of the contract to a new account (`newGovernor`). Can only be called by the current Governor. Must be claimed for this to complete\"},\"trusteeAddress()\":{\"notice\":\"Trustee contract that can collect a percentage of yield\"},\"trusteeFeeBps()\":{\"notice\":\"Amount of yield collected in basis points. eg 2000 = 20%\"},\"vaultBuffer()\":{\"notice\":\"Percentage of assets to keep in Vault to handle (most) withdrawals. 100% = 1e18.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vault/OETHVaultCore.sol\":\"OETHVaultCore\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (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 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 `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, 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 `sender` to `recipient` 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 sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\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\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\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 function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n// CAUTION\\n// This version of SafeMath should only be used with Solidity 0.8 or later,\\n// because it relies on the compiler's built in overflow checks.\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations.\\n *\\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\\n * now has built in overflow checking.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator.\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa2f576be637946f767aa56601c26d717f48a0aff44f82e46f13807eea1009a21\",\"license\":\"MIT\"},\"contracts/governance/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Base for contracts that are managed by the Origin Protocol's Governor.\\n * @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change\\n * from owner to governor and renounce methods removed. Does not use\\n * Context.sol like Ownable.sol does for simplification.\\n * @author Origin Protocol Inc\\n */\\ncontract Governable {\\n // Storage position of the owner and pendingOwner of the contract\\n // keccak256(\\\"OUSD.governor\\\");\\n bytes32 private constant governorPosition =\\n 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\\n\\n // keccak256(\\\"OUSD.pending.governor\\\");\\n bytes32 private constant pendingGovernorPosition =\\n 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\\n\\n // keccak256(\\\"OUSD.reentry.status\\\");\\n bytes32 private constant reentryStatusPosition =\\n 0x53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535;\\n\\n // See OpenZeppelin ReentrancyGuard implementation\\n uint256 constant _NOT_ENTERED = 1;\\n uint256 constant _ENTERED = 2;\\n\\n event PendingGovernorshipTransfer(\\n address indexed previousGovernor,\\n address indexed newGovernor\\n );\\n\\n event GovernorshipTransferred(\\n address indexed previousGovernor,\\n address indexed newGovernor\\n );\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial Governor.\\n */\\n constructor() {\\n _setGovernor(msg.sender);\\n emit GovernorshipTransferred(address(0), _governor());\\n }\\n\\n /**\\n * @notice Returns the address of the current Governor.\\n */\\n function governor() public view returns (address) {\\n return _governor();\\n }\\n\\n /**\\n * @dev Returns the address of the current Governor.\\n */\\n function _governor() internal view returns (address governorOut) {\\n bytes32 position = governorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n governorOut := sload(position)\\n }\\n }\\n\\n /**\\n * @dev Returns the address of the pending Governor.\\n */\\n function _pendingGovernor()\\n internal\\n view\\n returns (address pendingGovernor)\\n {\\n bytes32 position = pendingGovernorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n pendingGovernor := sload(position)\\n }\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the Governor.\\n */\\n modifier onlyGovernor() {\\n require(isGovernor(), \\\"Caller is not the Governor\\\");\\n _;\\n }\\n\\n /**\\n * @notice Returns true if the caller is the current Governor.\\n */\\n function isGovernor() public view returns (bool) {\\n return msg.sender == _governor();\\n }\\n\\n function _setGovernor(address newGovernor) internal {\\n bytes32 position = governorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n bytes32 position = reentryStatusPosition;\\n uint256 _reentry_status;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n _reentry_status := sload(position)\\n }\\n\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_reentry_status != _ENTERED, \\\"Reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, _ENTERED)\\n }\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, _NOT_ENTERED)\\n }\\n }\\n\\n function _setPendingGovernor(address newGovernor) internal {\\n bytes32 position = pendingGovernorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @notice Transfers Governance of the contract to a new account (`newGovernor`).\\n * Can only be called by the current Governor. Must be claimed for this to complete\\n * @param _newGovernor Address of the new Governor\\n */\\n function transferGovernance(address _newGovernor) external onlyGovernor {\\n _setPendingGovernor(_newGovernor);\\n emit PendingGovernorshipTransfer(_governor(), _newGovernor);\\n }\\n\\n /**\\n * @notice Claim Governance of the contract to a new account (`newGovernor`).\\n * Can only be called by the new Governor.\\n */\\n function claimGovernance() external {\\n require(\\n msg.sender == _pendingGovernor(),\\n \\\"Only the pending Governor can complete the claim\\\"\\n );\\n _changeGovernor(msg.sender);\\n }\\n\\n /**\\n * @dev Change Governance of the contract to a new account (`newGovernor`).\\n * @param _newGovernor Address of the new Governor\\n */\\n function _changeGovernor(address _newGovernor) internal {\\n require(_newGovernor != address(0), \\\"New Governor is address(0)\\\");\\n emit GovernorshipTransferred(_governor(), _newGovernor);\\n _setGovernor(_newGovernor);\\n }\\n}\\n\",\"keccak256\":\"0xb7133d6ce7a9e673ff79fcedb3fd41ae6e58e251f94915bb65731abe524270b4\",\"license\":\"MIT\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xa562062698aa12572123b36dfd2072f1a39e44fed2031cc19c2c9fd522f96ec2\",\"license\":\"MIT\"},\"contracts/interfaces/IGetExchangeRateToken.sol\":{\"content\":\"pragma solidity ^0.8.0;\\n\\ninterface IGetExchangeRateToken {\\n function getExchangeRate() external view returns (uint256 _exchangeRate);\\n}\\n\",\"keccak256\":\"0x641d5892d570f3f9e256d39a9571e58b02c39368726b01c4cdf7d91f45e349d8\"},\"contracts/interfaces/IOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOracle {\\n /**\\n * @dev returns the asset price in USD, in 8 decimal digits.\\n *\\n * The version of priceProvider deployed for OETH has 18 decimal digits\\n */\\n function price(address asset) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x9eabf152389f145c9c23ed71972af73fb1708cbc4b26e524a9ba29a557b7cfe5\",\"license\":\"MIT\"},\"contracts/interfaces/IStrategy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Platform interface to integrate with lending platform like Compound, AAVE etc.\\n */\\ninterface IStrategy {\\n /**\\n * @dev Deposit the given asset to platform\\n * @param _asset asset address\\n * @param _amount Amount to deposit\\n */\\n function deposit(address _asset, uint256 _amount) external;\\n\\n /**\\n * @dev Deposit the entire balance of all supported assets in the Strategy\\n * to the platform\\n */\\n function depositAll() external;\\n\\n /**\\n * @dev Withdraw given asset from Lending platform\\n */\\n function withdraw(\\n address _recipient,\\n address _asset,\\n uint256 _amount\\n ) external;\\n\\n /**\\n * @dev Liquidate all assets in strategy and return them to Vault.\\n */\\n function withdrawAll() external;\\n\\n /**\\n * @dev Returns the current balance of the given asset.\\n */\\n function checkBalance(address _asset)\\n external\\n view\\n returns (uint256 balance);\\n\\n /**\\n * @dev Returns bool indicating whether strategy supports asset.\\n */\\n function supportsAsset(address _asset) external view returns (bool);\\n\\n /**\\n * @dev Collect reward tokens from the Strategy.\\n */\\n function collectRewardTokens() external;\\n\\n /**\\n * @dev The address array of the reward tokens for the Strategy.\\n */\\n function getRewardTokenAddresses() external view returns (address[] memory);\\n}\\n\",\"keccak256\":\"0xb291e409a9b95527f9ed19cd6bff8eeb9921a21c1f5194a48c0bb9ce6613959a\",\"license\":\"MIT\"},\"contracts/token/OUSD.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OUSD Token Contract\\n * @dev ERC20 compatible contract for OUSD\\n * @dev Implements an elastic supply\\n * @author Origin Protocol Inc\\n */\\nimport { SafeMath } from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport { Initializable } from \\\"../utils/Initializable.sol\\\";\\nimport { InitializableERC20Detailed } from \\\"../utils/InitializableERC20Detailed.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\nimport { Governable } from \\\"../governance/Governable.sol\\\";\\n\\n/**\\n * NOTE that this is an ERC20 token but the invariant that the sum of\\n * balanceOf(x) for all x is not >= totalSupply(). This is a consequence of the\\n * rebasing design. Any integrations with OUSD should be aware.\\n */\\n\\ncontract OUSD is Initializable, InitializableERC20Detailed, Governable {\\n using SafeMath for uint256;\\n using StableMath for uint256;\\n\\n event TotalSupplyUpdatedHighres(\\n uint256 totalSupply,\\n uint256 rebasingCredits,\\n uint256 rebasingCreditsPerToken\\n );\\n event AccountRebasingEnabled(address account);\\n event AccountRebasingDisabled(address account);\\n\\n enum RebaseOptions {\\n NotSet,\\n OptOut,\\n OptIn\\n }\\n\\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\\n uint256 public _totalSupply;\\n mapping(address => mapping(address => uint256)) private _allowances;\\n address public vaultAddress = address(0);\\n mapping(address => uint256) private _creditBalances;\\n uint256 private _rebasingCredits;\\n uint256 private _rebasingCreditsPerToken;\\n // Frozen address/credits are non rebasing (value is held in contracts which\\n // do not receive yield unless they explicitly opt in)\\n uint256 public nonRebasingSupply;\\n mapping(address => uint256) public nonRebasingCreditsPerToken;\\n mapping(address => RebaseOptions) public rebaseState;\\n mapping(address => uint256) public isUpgraded;\\n\\n uint256 private constant RESOLUTION_INCREASE = 1e9;\\n\\n function initialize(\\n string calldata _nameArg,\\n string calldata _symbolArg,\\n address _vaultAddress,\\n uint256 _initialCreditsPerToken\\n ) external onlyGovernor initializer {\\n InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);\\n _rebasingCreditsPerToken = _initialCreditsPerToken;\\n vaultAddress = _vaultAddress;\\n }\\n\\n /**\\n * @dev Verifies that the caller is the Vault contract\\n */\\n modifier onlyVault() {\\n require(vaultAddress == msg.sender, \\\"Caller is not the Vault\\\");\\n _;\\n }\\n\\n /**\\n * @return The total supply of OUSD.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @return Low resolution rebasingCreditsPerToken\\n */\\n function rebasingCreditsPerToken() public view returns (uint256) {\\n return _rebasingCreditsPerToken / RESOLUTION_INCREASE;\\n }\\n\\n /**\\n * @return Low resolution total number of rebasing credits\\n */\\n function rebasingCredits() public view returns (uint256) {\\n return _rebasingCredits / RESOLUTION_INCREASE;\\n }\\n\\n /**\\n * @return High resolution rebasingCreditsPerToken\\n */\\n function rebasingCreditsPerTokenHighres() public view returns (uint256) {\\n return _rebasingCreditsPerToken;\\n }\\n\\n /**\\n * @return High resolution total number of rebasing credits\\n */\\n function rebasingCreditsHighres() public view returns (uint256) {\\n return _rebasingCredits;\\n }\\n\\n /**\\n * @dev Gets the balance of the specified address.\\n * @param _account Address to query the balance of.\\n * @return A uint256 representing the amount of base units owned by the\\n * specified address.\\n */\\n function balanceOf(address _account)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n if (_creditBalances[_account] == 0) return 0;\\n return\\n _creditBalances[_account].divPrecisely(_creditsPerToken(_account));\\n }\\n\\n /**\\n * @dev Gets the credits balance of the specified address.\\n * @dev Backwards compatible with old low res credits per token.\\n * @param _account The address to query the balance of.\\n * @return (uint256, uint256) Credit balance and credits per token of the\\n * address\\n */\\n function creditsBalanceOf(address _account)\\n public\\n view\\n returns (uint256, uint256)\\n {\\n uint256 cpt = _creditsPerToken(_account);\\n if (cpt == 1e27) {\\n // For a period before the resolution upgrade, we created all new\\n // contract accounts at high resolution. Since they are not changing\\n // as a result of this upgrade, we will return their true values\\n return (_creditBalances[_account], cpt);\\n } else {\\n return (\\n _creditBalances[_account] / RESOLUTION_INCREASE,\\n cpt / RESOLUTION_INCREASE\\n );\\n }\\n }\\n\\n /**\\n * @dev Gets the credits balance of the specified address.\\n * @param _account The address to query the balance of.\\n * @return (uint256, uint256, bool) Credit balance, credits per token of the\\n * address, and isUpgraded\\n */\\n function creditsBalanceOfHighres(address _account)\\n public\\n view\\n returns (\\n uint256,\\n uint256,\\n bool\\n )\\n {\\n return (\\n _creditBalances[_account],\\n _creditsPerToken(_account),\\n isUpgraded[_account] == 1\\n );\\n }\\n\\n /**\\n * @dev Transfer tokens to a specified address.\\n * @param _to the address to transfer to.\\n * @param _value the amount to be transferred.\\n * @return true on success.\\n */\\n function transfer(address _to, uint256 _value)\\n public\\n override\\n returns (bool)\\n {\\n require(_to != address(0), \\\"Transfer to zero address\\\");\\n require(\\n _value <= balanceOf(msg.sender),\\n \\\"Transfer greater than balance\\\"\\n );\\n\\n _executeTransfer(msg.sender, _to, _value);\\n\\n emit Transfer(msg.sender, _to, _value);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Transfer tokens from one address to another.\\n * @param _from The address you want to send tokens from.\\n * @param _to The address you want to transfer to.\\n * @param _value The amount of tokens to be transferred.\\n */\\n function transferFrom(\\n address _from,\\n address _to,\\n uint256 _value\\n ) public override returns (bool) {\\n require(_to != address(0), \\\"Transfer to zero address\\\");\\n require(_value <= balanceOf(_from), \\\"Transfer greater than balance\\\");\\n\\n _allowances[_from][msg.sender] = _allowances[_from][msg.sender].sub(\\n _value\\n );\\n\\n _executeTransfer(_from, _to, _value);\\n\\n emit Transfer(_from, _to, _value);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Update the count of non rebasing credits in response to a transfer\\n * @param _from The address you want to send tokens from.\\n * @param _to The address you want to transfer to.\\n * @param _value Amount of OUSD to transfer\\n */\\n function _executeTransfer(\\n address _from,\\n address _to,\\n uint256 _value\\n ) internal {\\n bool isNonRebasingTo = _isNonRebasingAccount(_to);\\n bool isNonRebasingFrom = _isNonRebasingAccount(_from);\\n\\n // Credits deducted and credited might be different due to the\\n // differing creditsPerToken used by each account\\n uint256 creditsCredited = _value.mulTruncate(_creditsPerToken(_to));\\n uint256 creditsDeducted = _value.mulTruncate(_creditsPerToken(_from));\\n\\n _creditBalances[_from] = _creditBalances[_from].sub(\\n creditsDeducted,\\n \\\"Transfer amount exceeds balance\\\"\\n );\\n _creditBalances[_to] = _creditBalances[_to].add(creditsCredited);\\n\\n if (isNonRebasingTo && !isNonRebasingFrom) {\\n // Transfer to non-rebasing account from rebasing account, credits\\n // are removed from the non rebasing tally\\n nonRebasingSupply = nonRebasingSupply.add(_value);\\n // Update rebasingCredits by subtracting the deducted amount\\n _rebasingCredits = _rebasingCredits.sub(creditsDeducted);\\n } else if (!isNonRebasingTo && isNonRebasingFrom) {\\n // Transfer to rebasing account from non-rebasing account\\n // Decreasing non-rebasing credits by the amount that was sent\\n nonRebasingSupply = nonRebasingSupply.sub(_value);\\n // Update rebasingCredits by adding the credited amount\\n _rebasingCredits = _rebasingCredits.add(creditsCredited);\\n }\\n }\\n\\n /**\\n * @dev Function to check the amount of tokens that _owner has allowed to\\n * `_spender`.\\n * @param _owner The address which owns the funds.\\n * @param _spender The address which will spend the funds.\\n * @return The number of tokens still available for the _spender.\\n */\\n function allowance(address _owner, address _spender)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n return _allowances[_owner][_spender];\\n }\\n\\n /**\\n * @dev Approve the passed address to spend the specified amount of tokens\\n * on behalf of msg.sender. This method is included for ERC20\\n * compatibility. `increaseAllowance` and `decreaseAllowance` should be\\n * used instead.\\n *\\n * Changing an allowance with this method brings the risk that someone\\n * may transfer both the old and the new allowance - if they are both\\n * greater than zero - if a transfer transaction is mined before the\\n * later approve() call is mined.\\n * @param _spender The address which will spend the funds.\\n * @param _value The amount of tokens to be spent.\\n */\\n function approve(address _spender, uint256 _value)\\n public\\n override\\n returns (bool)\\n {\\n _allowances[msg.sender][_spender] = _value;\\n emit Approval(msg.sender, _spender, _value);\\n return true;\\n }\\n\\n /**\\n * @dev Increase the amount of tokens that an owner has allowed to\\n * `_spender`.\\n * This method should be used instead of approve() to avoid the double\\n * approval vulnerability described above.\\n * @param _spender The address which will spend the funds.\\n * @param _addedValue The amount of tokens to increase the allowance by.\\n */\\n function increaseAllowance(address _spender, uint256 _addedValue)\\n public\\n returns (bool)\\n {\\n _allowances[msg.sender][_spender] = _allowances[msg.sender][_spender]\\n .add(_addedValue);\\n emit Approval(msg.sender, _spender, _allowances[msg.sender][_spender]);\\n return true;\\n }\\n\\n /**\\n * @dev Decrease the amount of tokens that an owner has allowed to\\n `_spender`.\\n * @param _spender The address which will spend the funds.\\n * @param _subtractedValue The amount of tokens to decrease the allowance\\n * by.\\n */\\n function decreaseAllowance(address _spender, uint256 _subtractedValue)\\n public\\n returns (bool)\\n {\\n uint256 oldValue = _allowances[msg.sender][_spender];\\n if (_subtractedValue >= oldValue) {\\n _allowances[msg.sender][_spender] = 0;\\n } else {\\n _allowances[msg.sender][_spender] = oldValue.sub(_subtractedValue);\\n }\\n emit Approval(msg.sender, _spender, _allowances[msg.sender][_spender]);\\n return true;\\n }\\n\\n /**\\n * @dev Mints new tokens, increasing totalSupply.\\n */\\n function mint(address _account, uint256 _amount) external onlyVault {\\n _mint(_account, _amount);\\n }\\n\\n /**\\n * @dev Creates `_amount` tokens and assigns them to `_account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address _account, uint256 _amount) internal nonReentrant {\\n require(_account != address(0), \\\"Mint to the zero address\\\");\\n\\n bool isNonRebasingAccount = _isNonRebasingAccount(_account);\\n\\n uint256 creditAmount = _amount.mulTruncate(_creditsPerToken(_account));\\n _creditBalances[_account] = _creditBalances[_account].add(creditAmount);\\n\\n // If the account is non rebasing and doesn't have a set creditsPerToken\\n // then set it i.e. this is a mint from a fresh contract\\n if (isNonRebasingAccount) {\\n nonRebasingSupply = nonRebasingSupply.add(_amount);\\n } else {\\n _rebasingCredits = _rebasingCredits.add(creditAmount);\\n }\\n\\n _totalSupply = _totalSupply.add(_amount);\\n\\n require(_totalSupply < MAX_SUPPLY, \\\"Max supply\\\");\\n\\n emit Transfer(address(0), _account, _amount);\\n }\\n\\n /**\\n * @dev Burns tokens, decreasing totalSupply.\\n */\\n function burn(address account, uint256 amount) external onlyVault {\\n _burn(account, amount);\\n }\\n\\n /**\\n * @dev Destroys `_amount` tokens from `_account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `_account` cannot be the zero address.\\n * - `_account` must have at least `_amount` tokens.\\n */\\n function _burn(address _account, uint256 _amount) internal nonReentrant {\\n require(_account != address(0), \\\"Burn from the zero address\\\");\\n if (_amount == 0) {\\n return;\\n }\\n\\n bool isNonRebasingAccount = _isNonRebasingAccount(_account);\\n uint256 creditAmount = _amount.mulTruncate(_creditsPerToken(_account));\\n uint256 currentCredits = _creditBalances[_account];\\n\\n // Remove the credits, burning rounding errors\\n if (\\n currentCredits == creditAmount || currentCredits - 1 == creditAmount\\n ) {\\n // Handle dust from rounding\\n _creditBalances[_account] = 0;\\n } else if (currentCredits > creditAmount) {\\n _creditBalances[_account] = _creditBalances[_account].sub(\\n creditAmount\\n );\\n } else {\\n revert(\\\"Remove exceeds balance\\\");\\n }\\n\\n // Remove from the credit tallies and non-rebasing supply\\n if (isNonRebasingAccount) {\\n nonRebasingSupply = nonRebasingSupply.sub(_amount);\\n } else {\\n _rebasingCredits = _rebasingCredits.sub(creditAmount);\\n }\\n\\n _totalSupply = _totalSupply.sub(_amount);\\n\\n emit Transfer(_account, address(0), _amount);\\n }\\n\\n /**\\n * @dev Get the credits per token for an account. Returns a fixed amount\\n * if the account is non-rebasing.\\n * @param _account Address of the account.\\n */\\n function _creditsPerToken(address _account)\\n internal\\n view\\n returns (uint256)\\n {\\n if (nonRebasingCreditsPerToken[_account] != 0) {\\n return nonRebasingCreditsPerToken[_account];\\n } else {\\n return _rebasingCreditsPerToken;\\n }\\n }\\n\\n /**\\n * @dev Is an account using rebasing accounting or non-rebasing accounting?\\n * Also, ensure contracts are non-rebasing if they have not opted in.\\n * @param _account Address of the account.\\n */\\n function _isNonRebasingAccount(address _account) internal returns (bool) {\\n bool isContract = Address.isContract(_account);\\n if (isContract && rebaseState[_account] == RebaseOptions.NotSet) {\\n _ensureRebasingMigration(_account);\\n }\\n return nonRebasingCreditsPerToken[_account] > 0;\\n }\\n\\n /**\\n * @dev Ensures internal account for rebasing and non-rebasing credits and\\n * supply is updated following deployment of frozen yield change.\\n */\\n function _ensureRebasingMigration(address _account) internal {\\n if (nonRebasingCreditsPerToken[_account] == 0) {\\n emit AccountRebasingDisabled(_account);\\n if (_creditBalances[_account] == 0) {\\n // Since there is no existing balance, we can directly set to\\n // high resolution, and do not have to do any other bookkeeping\\n nonRebasingCreditsPerToken[_account] = 1e27;\\n } else {\\n // Migrate an existing account:\\n\\n // Set fixed credits per token for this account\\n nonRebasingCreditsPerToken[_account] = _rebasingCreditsPerToken;\\n // Update non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.add(balanceOf(_account));\\n // Update credit tallies\\n _rebasingCredits = _rebasingCredits.sub(\\n _creditBalances[_account]\\n );\\n }\\n }\\n }\\n\\n /**\\n * @notice Enable rebasing for an account.\\n * @dev Add a contract address to the non-rebasing exception list. The\\n * address's balance will be part of rebases and the account will be exposed\\n * to upside and downside.\\n * @param _account Address of the account.\\n */\\n function governanceRebaseOptIn(address _account)\\n public\\n nonReentrant\\n onlyGovernor\\n {\\n _rebaseOptIn(_account);\\n }\\n\\n /**\\n * @dev Add a contract address to the non-rebasing exception list. The\\n * address's balance will be part of rebases and the account will be exposed\\n * to upside and downside.\\n */\\n function rebaseOptIn() public nonReentrant {\\n _rebaseOptIn(msg.sender);\\n }\\n\\n function _rebaseOptIn(address _account) internal {\\n require(_isNonRebasingAccount(_account), \\\"Account has not opted out\\\");\\n\\n // Convert balance into the same amount at the current exchange rate\\n uint256 newCreditBalance = _creditBalances[_account]\\n .mul(_rebasingCreditsPerToken)\\n .div(_creditsPerToken(_account));\\n\\n // Decreasing non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.sub(balanceOf(_account));\\n\\n _creditBalances[_account] = newCreditBalance;\\n\\n // Increase rebasing credits, totalSupply remains unchanged so no\\n // adjustment necessary\\n _rebasingCredits = _rebasingCredits.add(_creditBalances[_account]);\\n\\n rebaseState[_account] = RebaseOptions.OptIn;\\n\\n // Delete any fixed credits per token\\n delete nonRebasingCreditsPerToken[_account];\\n emit AccountRebasingEnabled(_account);\\n }\\n\\n /**\\n * @dev Explicitly mark that an address is non-rebasing.\\n */\\n function rebaseOptOut() public nonReentrant {\\n require(!_isNonRebasingAccount(msg.sender), \\\"Account has not opted in\\\");\\n\\n // Increase non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.add(balanceOf(msg.sender));\\n // Set fixed credits per token\\n nonRebasingCreditsPerToken[msg.sender] = _rebasingCreditsPerToken;\\n\\n // Decrease rebasing credits, total supply remains unchanged so no\\n // adjustment necessary\\n _rebasingCredits = _rebasingCredits.sub(_creditBalances[msg.sender]);\\n\\n // Mark explicitly opted out of rebasing\\n rebaseState[msg.sender] = RebaseOptions.OptOut;\\n emit AccountRebasingDisabled(msg.sender);\\n }\\n\\n /**\\n * @dev Modify the supply without minting new tokens. This uses a change in\\n * the exchange rate between \\\"credits\\\" and OUSD tokens to change balances.\\n * @param _newTotalSupply New total supply of OUSD.\\n */\\n function changeSupply(uint256 _newTotalSupply)\\n external\\n onlyVault\\n nonReentrant\\n {\\n require(_totalSupply > 0, \\\"Cannot increase 0 supply\\\");\\n\\n if (_totalSupply == _newTotalSupply) {\\n emit TotalSupplyUpdatedHighres(\\n _totalSupply,\\n _rebasingCredits,\\n _rebasingCreditsPerToken\\n );\\n return;\\n }\\n\\n _totalSupply = _newTotalSupply > MAX_SUPPLY\\n ? MAX_SUPPLY\\n : _newTotalSupply;\\n\\n _rebasingCreditsPerToken = _rebasingCredits.divPrecisely(\\n _totalSupply.sub(nonRebasingSupply)\\n );\\n\\n require(_rebasingCreditsPerToken > 0, \\\"Invalid change in supply\\\");\\n\\n _totalSupply = _rebasingCredits\\n .divPrecisely(_rebasingCreditsPerToken)\\n .add(nonRebasingSupply);\\n\\n emit TotalSupplyUpdatedHighres(\\n _totalSupply,\\n _rebasingCredits,\\n _rebasingCreditsPerToken\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2dc66b1ba02716d64eb47dd9117fda62650d8b57669e6c351437e0ad29ad5f19\",\"license\":\"MIT\"},\"contracts/utils/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { IBasicToken } from \\\"../interfaces/IBasicToken.sol\\\";\\n\\nlibrary Helpers {\\n /**\\n * @notice Fetch the `symbol()` from an ERC20 token\\n * @dev Grabs the `symbol()` from a contract\\n * @param _token Address of the ERC20 token\\n * @return string Symbol of the ERC20 token\\n */\\n function getSymbol(address _token) internal view returns (string memory) {\\n string memory symbol = IBasicToken(_token).symbol();\\n return symbol;\\n }\\n\\n /**\\n * @notice Fetch the `decimals()` from an ERC20 token\\n * @dev Grabs the `decimals()` from a contract and fails if\\n * the decimal value does not live within a certain range\\n * @param _token Address of the ERC20 token\\n * @return uint256 Decimals of the ERC20 token\\n */\\n function getDecimals(address _token) internal view returns (uint256) {\\n uint256 decimals = IBasicToken(_token).decimals();\\n require(\\n decimals >= 4 && decimals <= 18,\\n \\\"Token must have sufficient decimal places\\\"\\n );\\n\\n return decimals;\\n }\\n}\\n\",\"keccak256\":\"0x108b7a69e0140da0072ca18f90a03a3340574400f81aa6076cd2cccdf13699c2\",\"license\":\"MIT\"},\"contracts/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Base contract any contracts that need to initialize state after deployment.\\n * @author Origin Protocol Inc\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n require(\\n initializing || !initialized,\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0xaadbcc138114afed4af4f353c2ced2916e6ee14be91434789187f192caf0d786\",\"license\":\"MIT\"},\"contracts/utils/InitializableERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @dev Optional functions from the ERC20 standard.\\n * Converted from openzeppelin/contracts/token/ERC20/ERC20Detailed.sol\\n * @author Origin Protocol Inc\\n */\\nabstract contract InitializableERC20Detailed is IERC20 {\\n // Storage gap to skip storage from prior to OUSD reset\\n uint256[100] private _____gap;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\\n * these values are immutable: they can only be set once during\\n * construction.\\n * @notice To avoid variable shadowing appended `Arg` after arguments name.\\n */\\n function _initialize(\\n string memory nameArg,\\n string memory symbolArg,\\n uint8 decimalsArg\\n ) internal {\\n _name = nameArg;\\n _symbol = symbolArg;\\n _decimals = decimalsArg;\\n }\\n\\n /**\\n * @notice Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @notice Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @notice Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n}\\n\",\"keccak256\":\"0xe35ac2d813a30d845a3b52bba72588d7e936c2b3f3373d15568c14db46aeed60\",\"license\":\"MIT\"},\"contracts/utils/StableMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\n\\n// Based on StableMath from Stability Labs Pty. Ltd.\\n// https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol\\n\\nlibrary StableMath {\\n using SafeMath for uint256;\\n\\n /**\\n * @dev Scaling unit for use in specific calculations,\\n * where 1 * 10**18, or 1e18 represents a unit '1'\\n */\\n uint256 private constant FULL_SCALE = 1e18;\\n\\n /***************************************\\n Helpers\\n ****************************************/\\n\\n /**\\n * @dev Adjust the scale of an integer\\n * @param to Decimals to scale to\\n * @param from Decimals to scale from\\n */\\n function scaleBy(\\n uint256 x,\\n uint256 to,\\n uint256 from\\n ) internal pure returns (uint256) {\\n if (to > from) {\\n x = x.mul(10**(to - from));\\n } else if (to < from) {\\n // slither-disable-next-line divide-before-multiply\\n x = x.div(10**(from - to));\\n }\\n return x;\\n }\\n\\n /***************************************\\n Precise Arithmetic\\n ****************************************/\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the full scale\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit\\n */\\n function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulTruncateScale(x, y, FULL_SCALE);\\n }\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the given scale. For example,\\n * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @param scale Scale unit\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit\\n */\\n function mulTruncateScale(\\n uint256 x,\\n uint256 y,\\n uint256 scale\\n ) internal pure returns (uint256) {\\n // e.g. assume scale = fullScale\\n // z = 10e18 * 9e17 = 9e36\\n uint256 z = x.mul(y);\\n // return 9e36 / 1e18 = 9e18\\n return z.div(scale);\\n }\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit, rounded up to the closest base unit.\\n */\\n function mulTruncateCeil(uint256 x, uint256 y)\\n internal\\n pure\\n returns (uint256)\\n {\\n // e.g. 8e17 * 17268172638 = 138145381104e17\\n uint256 scaled = x.mul(y);\\n // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17\\n uint256 ceil = scaled.add(FULL_SCALE.sub(1));\\n // e.g. 13814538111.399...e18 / 1e18 = 13814538111\\n return ceil.div(FULL_SCALE);\\n }\\n\\n /**\\n * @dev Precisely divides two units, by first scaling the left hand operand. Useful\\n * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)\\n * @param x Left hand input to division\\n * @param y Right hand input to division\\n * @return Result after multiplying the left operand by the scale, and\\n * executing the division on the right hand input.\\n */\\n function divPrecisely(uint256 x, uint256 y)\\n internal\\n pure\\n returns (uint256)\\n {\\n // e.g. 8e18 * 1e18 = 8e36\\n uint256 z = x.mul(FULL_SCALE);\\n // e.g. 8e36 / 10e18 = 8e17\\n return z.div(y);\\n }\\n}\\n\",\"keccak256\":\"0x1eb49f6f79045d9e0a8e1dced8e01d9e559e5fac554dcbb53e43140b601b04e7\",\"license\":\"MIT\"},\"contracts/vault/OETHVaultCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { VaultCore } from \\\"./VaultCore.sol\\\";\\n\\n/**\\n * @title OETH VaultCore Contract\\n * @author Origin Protocol Inc\\n */\\ncontract OETHVaultCore is VaultCore {\\n address public immutable weth;\\n\\n constructor(address _weth) {\\n weth = _weth;\\n }\\n\\n // @inheritdoc VaultCore\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external virtual override whenNotCapitalPaused nonReentrant {\\n require(_asset == weth, \\\"Unsupported asset for minting\\\");\\n _mint(_asset, _amount, _minimumOusdAmount);\\n }\\n}\\n\",\"keccak256\":\"0x1f5477af75cc7c34493d5098a1814d91e7c439bef468d44dcd69090fdbc89bbb\",\"license\":\"MIT\"},\"contracts/vault/VaultCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OToken VaultCore contract\\n * @notice The Vault contract stores assets. On a deposit, OTokens will be minted\\n and sent to the depositor. On a withdrawal, OTokens will be burned and\\n assets will be sent to the withdrawer. The Vault accepts deposits of\\n interest from yield bearing strategies which will modify the supply\\n of OTokens.\\n * @author Origin Protocol Inc\\n */\\n\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\nimport { IOracle } from \\\"../interfaces/IOracle.sol\\\";\\nimport { IGetExchangeRateToken } from \\\"../interfaces/IGetExchangeRateToken.sol\\\";\\n\\nimport \\\"./VaultInitializer.sol\\\";\\n\\ncontract VaultCore is VaultInitializer {\\n using SafeERC20 for IERC20;\\n using StableMath for uint256;\\n // max signed int\\n uint256 internal constant MAX_INT = 2**255 - 1;\\n // max un-signed int\\n uint256 internal constant MAX_UINT =\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n\\n /**\\n * @dev Verifies that the rebasing is not paused.\\n */\\n modifier whenNotRebasePaused() {\\n require(!rebasePaused, \\\"Rebasing paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Verifies that the deposits are not paused.\\n */\\n modifier whenNotCapitalPaused() {\\n require(!capitalPaused, \\\"Capital paused\\\");\\n _;\\n }\\n\\n modifier onlyOusdMetaStrategy() {\\n require(\\n msg.sender == ousdMetaStrategy,\\n \\\"Caller is not the OUSD meta strategy\\\"\\n );\\n _;\\n }\\n\\n /**\\n * @notice Deposit a supported asset and mint OTokens.\\n * @param _asset Address of the asset being deposited\\n * @param _amount Amount of the asset being deposited\\n * @param _minimumOusdAmount Minimum OTokens to mint\\n */\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external virtual whenNotCapitalPaused nonReentrant {\\n _mint(_asset, _amount, _minimumOusdAmount);\\n }\\n\\n function _mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) internal {\\n require(assets[_asset].isSupported, \\\"Asset is not supported\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 units = _toUnits(_amount, _asset);\\n uint256 unitPrice = _toUnitPrice(_asset, true);\\n uint256 priceAdjustedDeposit = (units * unitPrice) / 1e18;\\n\\n if (_minimumOusdAmount > 0) {\\n require(\\n priceAdjustedDeposit >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n }\\n\\n emit Mint(msg.sender, priceAdjustedDeposit);\\n\\n // Rebase must happen before any transfers occur.\\n if (priceAdjustedDeposit >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n // Mint matching amount of OTokens\\n oUSD.mint(msg.sender, priceAdjustedDeposit);\\n\\n // Transfer the deposited coins to the vault\\n IERC20 asset = IERC20(_asset);\\n asset.safeTransferFrom(msg.sender, address(this), _amount);\\n\\n if (priceAdjustedDeposit >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @notice Mint OTokens for a Metapool Strategy\\n * @param _amount Amount of the asset being deposited\\n *\\n * Notice: can't use `nonReentrant` modifier since the `mint` function can\\n * call `allocate`, and that can trigger `ConvexOUSDMetaStrategy` to call this function\\n * while the execution of the `mint` has not yet completed -> causing a `nonReentrant` collision.\\n *\\n * Also important to understand is that this is a limitation imposed by the test suite.\\n * Production / mainnet contracts should never be configured in a way where mint/redeem functions\\n * that are moving funds between the Vault and end user wallets can influence strategies\\n * utilizing this function.\\n */\\n function mintForStrategy(uint256 _amount)\\n external\\n whenNotCapitalPaused\\n onlyOusdMetaStrategy\\n {\\n require(_amount < MAX_INT, \\\"Amount too high\\\");\\n\\n emit Mint(msg.sender, _amount);\\n\\n // safe to cast because of the require check at the beginning of the function\\n netOusdMintedForStrategy += int256(_amount);\\n\\n require(\\n abs(netOusdMintedForStrategy) < netOusdMintForStrategyThreshold,\\n \\\"Minted ousd surpassed netOusdMintForStrategyThreshold.\\\"\\n );\\n\\n // Mint matching amount of OTokens\\n oUSD.mint(msg.sender, _amount);\\n }\\n\\n // In memoriam\\n\\n /**\\n * @notice Withdraw a supported asset and burn OTokens.\\n * @param _amount Amount of OTokens to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n _redeem(_amount, _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn OTokens.\\n * @param _amount Amount of OTokens to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount) internal {\\n // Calculate redemption outputs\\n uint256[] memory outputs = _calculateRedeemOutputs(_amount);\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // Send outputs\\n uint256 assetCount = allAssets.length;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n if (outputs[i] == 0) continue;\\n\\n address assetAddr = allAssets[i];\\n\\n if (IERC20(assetAddr).balanceOf(address(this)) >= outputs[i]) {\\n // Use Vault funds first if sufficient\\n IERC20(assetAddr).safeTransfer(msg.sender, outputs[i]);\\n } else {\\n address strategyAddr = assetDefaultStrategies[assetAddr];\\n if (strategyAddr != address(0)) {\\n // Nothing in Vault, but something in Strategy, send from there\\n IStrategy strategy = IStrategy(strategyAddr);\\n strategy.withdraw(msg.sender, assetAddr, outputs[i]);\\n } else {\\n // Cant find funds anywhere\\n revert(\\\"Liquidity error\\\");\\n }\\n }\\n }\\n\\n if (_minimumUnitAmount > 0) {\\n uint256 unitTotal = 0;\\n for (uint256 i = 0; i < outputs.length; ++i) {\\n unitTotal += _toUnits(outputs[i], allAssets[i]);\\n }\\n require(\\n unitTotal >= _minimumUnitAmount,\\n \\\"Redeem amount lower than minimum\\\"\\n );\\n }\\n\\n oUSD.burn(msg.sender, _amount);\\n\\n // Until we can prove that we won't affect the prices of our assets\\n // by withdrawing them, this should be here.\\n // It's possible that a strategy was off on its asset total, perhaps\\n // a reward token sold for more or for less than anticipated.\\n uint256 totalUnits = 0;\\n if (_amount >= rebaseThreshold && !rebasePaused) {\\n totalUnits = _rebase();\\n } else {\\n totalUnits = _totalValue();\\n }\\n\\n // Check that the OTokens are backed by enough assets\\n if (maxSupplyDiff > 0) {\\n // Allow a max difference of maxSupplyDiff% between\\n // backing assets value and OUSD total supply\\n uint256 diff = oUSD.totalSupply().divPrecisely(totalUnits);\\n require(\\n (diff > 1e18 ? diff - 1e18 : 1e18 - diff) <= maxSupplyDiff,\\n \\\"Backing supply liquidity error\\\"\\n );\\n }\\n }\\n\\n /**\\n * @notice Burn OTokens for Metapool Strategy\\n * @param _amount Amount of OUSD to burn\\n *\\n * @dev Notice: can't use `nonReentrant` modifier since the `redeem` function could\\n * require withdrawal on `ConvexOUSDMetaStrategy` and that one can call `burnForStrategy`\\n * while the execution of the `redeem` has not yet completed -> causing a `nonReentrant` collision.\\n *\\n * Also important to understand is that this is a limitation imposed by the test suite.\\n * Production / mainnet contracts should never be configured in a way where mint/redeem functions\\n * that are moving funds between the Vault and end user wallets can influence strategies\\n * utilizing this function.\\n */\\n function burnForStrategy(uint256 _amount)\\n external\\n whenNotCapitalPaused\\n onlyOusdMetaStrategy\\n {\\n require(_amount < MAX_INT, \\\"Amount too high\\\");\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // safe to cast because of the require check at the beginning of the function\\n netOusdMintedForStrategy -= int256(_amount);\\n\\n require(\\n abs(netOusdMintedForStrategy) < netOusdMintForStrategyThreshold,\\n \\\"Attempting to burn too much OUSD.\\\"\\n );\\n\\n // Burn OTokens\\n oUSD.burn(msg.sender, _amount);\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn all OTokens.\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeemAll(uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n _redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\n **/\\n function allocate() external whenNotCapitalPaused nonReentrant {\\n _allocate();\\n }\\n\\n /**\\n * @dev Allocate unallocated funds on Vault to strategies.\\n **/\\n function _allocate() internal {\\n uint256 vaultValue = _totalValueInVault();\\n // Nothing in vault to allocate\\n if (vaultValue == 0) return;\\n uint256 strategiesValue = _totalValueInStrategies();\\n // We have a method that does the same as this, gas optimisation\\n uint256 calculatedTotalValue = vaultValue + strategiesValue;\\n\\n // We want to maintain a buffer on the Vault so calculate a percentage\\n // modifier to multiply each amount being allocated by to enforce the\\n // vault buffer\\n uint256 vaultBufferModifier;\\n if (strategiesValue == 0) {\\n // Nothing in Strategies, allocate 100% minus the vault buffer to\\n // strategies\\n vaultBufferModifier = uint256(1e18) - vaultBuffer;\\n } else {\\n vaultBufferModifier =\\n (vaultBuffer * calculatedTotalValue) /\\n vaultValue;\\n if (1e18 > vaultBufferModifier) {\\n // E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17\\n // (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault\\n vaultBufferModifier = uint256(1e18) - vaultBufferModifier;\\n } else {\\n // We need to let the buffer fill\\n return;\\n }\\n }\\n if (vaultBufferModifier == 0) return;\\n\\n // Iterate over all assets in the Vault and allocate to the appropriate\\n // strategy\\n uint256 assetCount = allAssets.length;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n IERC20 asset = IERC20(allAssets[i]);\\n uint256 assetBalance = asset.balanceOf(address(this));\\n // No balance, nothing to do here\\n if (assetBalance == 0) continue;\\n\\n // Multiply the balance by the vault buffer modifier and truncate\\n // to the scale of the asset decimals\\n uint256 allocateAmount = assetBalance.mulTruncate(\\n vaultBufferModifier\\n );\\n\\n address depositStrategyAddr = assetDefaultStrategies[\\n address(asset)\\n ];\\n\\n if (depositStrategyAddr != address(0) && allocateAmount > 0) {\\n IStrategy strategy = IStrategy(depositStrategyAddr);\\n // Transfer asset to Strategy and call deposit method to\\n // mint or take required action\\n asset.safeTransfer(address(strategy), allocateAmount);\\n strategy.deposit(address(asset), allocateAmount);\\n emit AssetAllocated(\\n address(asset),\\n depositStrategyAddr,\\n allocateAmount\\n );\\n }\\n }\\n }\\n\\n /**\\n * @notice Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OTokens.\\n */\\n function rebase() external virtual nonReentrant {\\n _rebase();\\n }\\n\\n /**\\n * @dev Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OTokens, optionally sending a\\n * portion of the yield to the trustee.\\n * @return totalUnits Total balance of Vault in units\\n */\\n function _rebase() internal whenNotRebasePaused returns (uint256) {\\n uint256 ousdSupply = oUSD.totalSupply();\\n uint256 vaultValue = _totalValue();\\n if (ousdSupply == 0) {\\n return vaultValue;\\n }\\n\\n // Yield fee collection\\n address _trusteeAddress = trusteeAddress; // gas savings\\n if (_trusteeAddress != address(0) && (vaultValue > ousdSupply)) {\\n uint256 yield = vaultValue - ousdSupply;\\n uint256 fee = yield.mulTruncateScale(trusteeFeeBps, 1e4);\\n require(yield > fee, \\\"Fee must not be greater than yield\\\");\\n if (fee > 0) {\\n oUSD.mint(_trusteeAddress, fee);\\n }\\n emit YieldDistribution(_trusteeAddress, yield, fee);\\n }\\n\\n // Only rachet OToken supply upwards\\n ousdSupply = oUSD.totalSupply(); // Final check should use latest value\\n if (vaultValue > ousdSupply) {\\n oUSD.changeSupply(vaultValue);\\n }\\n return vaultValue;\\n }\\n\\n /**\\n * @notice Determine the total value of assets held by the vault and its\\n * strategies.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function totalValue() external view virtual returns (uint256 value) {\\n value = _totalValue();\\n }\\n\\n /**\\n * @dev Internal Calculate the total value of the assets held by the\\n * vault and its strategies.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValue() internal view virtual returns (uint256 value) {\\n return _totalValueInVault() + _totalValueInStrategies();\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Vault.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValueInVault() internal view returns (uint256 value) {\\n uint256 assetCount = allAssets.length;\\n for (uint256 y = 0; y < assetCount; ++y) {\\n address assetAddr = allAssets[y];\\n uint256 balance = IERC20(assetAddr).balanceOf(address(this));\\n if (balance > 0) {\\n value += _toUnits(balance, assetAddr);\\n }\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Strategies.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValueInStrategies() internal view returns (uint256 value) {\\n uint256 stratCount = allStrategies.length;\\n for (uint256 i = 0; i < stratCount; ++i) {\\n value = value + _totalValueInStrategy(allStrategies[i]);\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held by strategy.\\n * @param _strategyAddr Address of the strategy\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValueInStrategy(address _strategyAddr)\\n internal\\n view\\n returns (uint256 value)\\n {\\n IStrategy strategy = IStrategy(_strategyAddr);\\n uint256 assetCount = allAssets.length;\\n for (uint256 y = 0; y < assetCount; ++y) {\\n address assetAddr = allAssets[y];\\n if (strategy.supportsAsset(assetAddr)) {\\n uint256 balance = strategy.checkBalance(assetAddr);\\n if (balance > 0) {\\n value += _toUnits(balance, assetAddr);\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Get the balance of an asset held in Vault and all strategies.\\n * @param _asset Address of asset\\n * @return uint256 Balance of asset in decimals of asset\\n */\\n function checkBalance(address _asset) external view returns (uint256) {\\n return _checkBalance(_asset);\\n }\\n\\n /**\\n * @notice Get the balance of an asset held in Vault and all strategies.\\n * @param _asset Address of asset\\n * @return balance Balance of asset in decimals of asset\\n */\\n function _checkBalance(address _asset)\\n internal\\n view\\n virtual\\n returns (uint256 balance)\\n {\\n IERC20 asset = IERC20(_asset);\\n balance = asset.balanceOf(address(this));\\n uint256 stratCount = allStrategies.length;\\n for (uint256 i = 0; i < stratCount; ++i) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n if (strategy.supportsAsset(_asset)) {\\n balance = balance + strategy.checkBalance(_asset);\\n }\\n }\\n }\\n\\n /**\\n * @notice Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned\\n */\\n function calculateRedeemOutputs(uint256 _amount)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n return _calculateRedeemOutputs(_amount);\\n }\\n\\n /**\\n * @dev Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned.\\n * @return outputs Array of amounts respective to the supported assets\\n */\\n function _calculateRedeemOutputs(uint256 _amount)\\n internal\\n view\\n returns (uint256[] memory outputs)\\n {\\n // We always give out coins in proportion to how many we have,\\n // Now if all coins were the same value, this math would easy,\\n // just take the percentage of each coin, and multiply by the\\n // value to be given out. But if coins are worth more than $1,\\n // then we would end up handing out too many coins. We need to\\n // adjust by the total value of coins.\\n //\\n // To do this, we total up the value of our coins, by their\\n // percentages. Then divide what we would otherwise give out by\\n // this number.\\n //\\n // Let say we have 100 DAI at $1.06 and 200 USDT at $1.00.\\n // So for every 1 DAI we give out, we'll be handing out 2 USDT\\n // Our total output ratio is: 33% * 1.06 + 66% * 1.00 = 1.02\\n //\\n // So when calculating the output, we take the percentage of\\n // each coin, times the desired output value, divided by the\\n // totalOutputRatio.\\n //\\n // For example, withdrawing: 30 OUSD:\\n // DAI 33% * 30 / 1.02 = 9.80 DAI\\n // USDT = 66 % * 30 / 1.02 = 19.60 USDT\\n //\\n // Checking these numbers:\\n // 9.80 DAI * 1.06 = $10.40\\n // 19.60 USDT * 1.00 = $19.60\\n //\\n // And so the user gets $10.40 + $19.60 = $30 worth of value.\\n\\n uint256 assetCount = allAssets.length;\\n uint256[] memory assetUnits = new uint256[](assetCount);\\n uint256[] memory assetBalances = new uint256[](assetCount);\\n outputs = new uint256[](assetCount);\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mulTruncateScale(redeemFeeBps, 1e4);\\n _amount = _amount - redeemFee;\\n }\\n\\n // Calculate assets balances and decimals once,\\n // for a large gas savings.\\n uint256 totalUnits = 0;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n address assetAddr = allAssets[i];\\n uint256 balance = _checkBalance(assetAddr);\\n assetBalances[i] = balance;\\n assetUnits[i] = _toUnits(balance, assetAddr);\\n totalUnits = totalUnits + assetUnits[i];\\n }\\n // Calculate totalOutputRatio\\n uint256 totalOutputRatio = 0;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n uint256 unitPrice = _toUnitPrice(allAssets[i], false);\\n uint256 ratio = (assetUnits[i] * unitPrice) / totalUnits;\\n totalOutputRatio = totalOutputRatio + ratio;\\n }\\n // Calculate final outputs\\n uint256 factor = _amount.divPrecisely(totalOutputRatio);\\n for (uint256 i = 0; i < assetCount; ++i) {\\n outputs[i] = (assetBalances[i] * factor) / totalUnits;\\n }\\n }\\n\\n /***************************************\\n Pricing\\n ****************************************/\\n\\n /**\\n * @notice Returns the total price in 18 digit units for a given asset.\\n * Never goes above 1, since that is how we price mints.\\n * @param asset address of the asset\\n * @return price uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\\n */\\n function priceUnitMint(address asset)\\n external\\n view\\n returns (uint256 price)\\n {\\n /* need to supply 1 asset unit in asset's decimals and can not just hard-code\\n * to 1e18 and ignore calling `_toUnits` since we need to consider assets\\n * with the exchange rate\\n */\\n uint256 units = _toUnits(\\n uint256(1e18).scaleBy(_getDecimals(asset), 18),\\n asset\\n );\\n price = (_toUnitPrice(asset, true) * units) / 1e18;\\n }\\n\\n /**\\n * @notice Returns the total price in 18 digit unit for a given asset.\\n * Never goes below 1, since that is how we price redeems\\n * @param asset Address of the asset\\n * @return price uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\\n */\\n function priceUnitRedeem(address asset)\\n external\\n view\\n returns (uint256 price)\\n {\\n /* need to supply 1 asset unit in asset's decimals and can not just hard-code\\n * to 1e18 and ignore calling `_toUnits` since we need to consider assets\\n * with the exchange rate\\n */\\n uint256 units = _toUnits(\\n uint256(1e18).scaleBy(_getDecimals(asset), 18),\\n asset\\n );\\n price = (_toUnitPrice(asset, false) * units) / 1e18;\\n }\\n\\n /***************************************\\n Utils\\n ****************************************/\\n\\n /**\\n * @dev Convert a quantity of a token into 1e18 fixed decimal \\\"units\\\"\\n * in the underlying base (USD/ETH) used by the vault.\\n * Price is not taken into account, only quantity.\\n *\\n * Examples of this conversion:\\n *\\n * - 1e18 DAI becomes 1e18 units (same decimals)\\n * - 1e6 USDC becomes 1e18 units (decimal conversion)\\n * - 1e18 rETH becomes 1.2e18 units (exchange rate conversion)\\n *\\n * @param _raw Quantity of asset\\n * @param _asset Core Asset address\\n * @return value 1e18 normalized quantity of units\\n */\\n function _toUnits(uint256 _raw, address _asset)\\n internal\\n view\\n returns (uint256)\\n {\\n UnitConversion conversion = assets[_asset].unitConversion;\\n if (conversion == UnitConversion.DECIMALS) {\\n return _raw.scaleBy(18, _getDecimals(_asset));\\n } else if (conversion == UnitConversion.GETEXCHANGERATE) {\\n uint256 exchangeRate = IGetExchangeRateToken(_asset)\\n .getExchangeRate();\\n return (_raw * exchangeRate) / 1e18;\\n } else {\\n revert(\\\"Unsupported conversion type\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns asset's unit price accounting for different asset types\\n * and takes into account the context in which that price exists -\\n * - mint or redeem.\\n *\\n * Note: since we are returning the price of the unit and not the one of the\\n * asset (see comment above how 1 rETH exchanges for 1.2 units) we need\\n * to make the Oracle price adjustment as well since we are pricing the\\n * units and not the assets.\\n *\\n * The price also snaps to a \\\"full unit price\\\" in case a mint or redeem\\n * action would be unfavourable to the protocol.\\n *\\n */\\n function _toUnitPrice(address _asset, bool isMint)\\n internal\\n view\\n returns (uint256 price)\\n {\\n UnitConversion conversion = assets[_asset].unitConversion;\\n price = IOracle(priceProvider).price(_asset);\\n\\n if (conversion == UnitConversion.GETEXCHANGERATE) {\\n uint256 exchangeRate = IGetExchangeRateToken(_asset)\\n .getExchangeRate();\\n price = (price * 1e18) / exchangeRate;\\n } else if (conversion != UnitConversion.DECIMALS) {\\n revert(\\\"Unsupported conversion type\\\");\\n }\\n\\n /* At this stage the price is already adjusted to the unit\\n * so the price checks are agnostic to underlying asset being\\n * pegged to a USD or to an ETH or having a custom exchange rate.\\n */\\n require(price <= MAX_UNIT_PRICE_DRIFT, \\\"Vault: Price exceeds max\\\");\\n require(price >= MIN_UNIT_PRICE_DRIFT, \\\"Vault: Price under min\\\");\\n\\n if (isMint) {\\n /* Never price a normalized unit price for more than one\\n * unit of OETH/OUSD when minting.\\n */\\n if (price > 1e18) {\\n price = 1e18;\\n }\\n require(price >= MINT_MINIMUM_UNIT_PRICE, \\\"Asset price below peg\\\");\\n } else {\\n /* Never give out more than 1 normalized unit amount of assets\\n * for one unit of OETH/OUSD when redeeming.\\n */\\n if (price < 1e18) {\\n price = 1e18;\\n }\\n }\\n }\\n\\n function _getDecimals(address _asset)\\n internal\\n view\\n returns (uint256 decimals)\\n {\\n decimals = assets[_asset].decimals;\\n require(decimals > 0, \\\"Decimals not cached\\\");\\n }\\n\\n /**\\n * @notice Return the number of assets supported by the Vault.\\n */\\n function getAssetCount() public view returns (uint256) {\\n return allAssets.length;\\n }\\n\\n /**\\n * @notice Gets the vault configuration of a supported asset.\\n */\\n function getAssetConfig(address _asset)\\n public\\n view\\n returns (Asset memory config)\\n {\\n config = assets[_asset];\\n }\\n\\n /**\\n * @notice Return all vault asset addresses in order\\n */\\n function getAllAssets() external view returns (address[] memory) {\\n return allAssets;\\n }\\n\\n /**\\n * @notice Return the number of strategies active on the Vault.\\n */\\n function getStrategyCount() external view returns (uint256) {\\n return allStrategies.length;\\n }\\n\\n /**\\n * @notice Return the array of all strategies\\n */\\n function getAllStrategies() external view returns (address[] memory) {\\n return allStrategies;\\n }\\n\\n /**\\n * @notice Returns whether the vault supports the asset\\n * @param _asset address of the asset\\n * @return true if supported\\n */\\n function isSupportedAsset(address _asset) external view returns (bool) {\\n return assets[_asset].isSupported;\\n }\\n\\n /**\\n * @dev Falldown to the admin implementation\\n * @notice This is a catch all for all functions not declared in core\\n */\\n // solhint-disable-next-line no-complex-fallback\\n fallback() external {\\n bytes32 slot = adminImplPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(\\n gas(),\\n sload(slot),\\n 0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n function abs(int256 x) private pure returns (uint256) {\\n require(x < int256(MAX_INT), \\\"Amount too high\\\");\\n return x >= 0 ? uint256(x) : uint256(-x);\\n }\\n}\\n\",\"keccak256\":\"0x7e7d922a11616f17716fc0511ac1b8072819cc9e933bb4038f050c8e644b565a\",\"license\":\"MIT\"},\"contracts/vault/VaultInitializer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OToken VaultInitializer contract\\n * @notice The Vault contract initializes the vault.\\n * @author Origin Protocol Inc\\n */\\n\\nimport \\\"./VaultStorage.sol\\\";\\n\\ncontract VaultInitializer is VaultStorage {\\n function initialize(address _priceProvider, address _oToken)\\n external\\n onlyGovernor\\n initializer\\n {\\n require(_priceProvider != address(0), \\\"PriceProvider address is zero\\\");\\n require(_oToken != address(0), \\\"oToken address is zero\\\");\\n\\n oUSD = OUSD(_oToken);\\n\\n priceProvider = _priceProvider;\\n\\n rebasePaused = false;\\n capitalPaused = true;\\n\\n // Initial redeem fee of 0 basis points\\n redeemFeeBps = 0;\\n // Initial Vault buffer of 0%\\n vaultBuffer = 0;\\n // Initial allocate threshold of 25,000 OUSD\\n autoAllocateThreshold = 25000e18;\\n // Threshold for rebasing\\n rebaseThreshold = 1000e18;\\n // Initialize all strategies\\n allStrategies = new address[](0);\\n }\\n}\\n\",\"keccak256\":\"0x5b9676307bbabe14b5278f00ec7edc557b84debbfa1391902d78100cb9cd467e\",\"license\":\"MIT\"},\"contracts/vault/VaultStorage.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OToken VaultStorage contract\\n * @notice The VaultStorage contract defines the storage for the Vault contracts\\n * @author Origin Protocol Inc\\n */\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport { IStrategy } from \\\"../interfaces/IStrategy.sol\\\";\\nimport { Governable } from \\\"../governance/Governable.sol\\\";\\nimport { OUSD } from \\\"../token/OUSD.sol\\\";\\nimport { Initializable } from \\\"../utils/Initializable.sol\\\";\\nimport \\\"../utils/Helpers.sol\\\";\\n\\ncontract VaultStorage is Initializable, Governable {\\n using SafeERC20 for IERC20;\\n\\n event AssetSupported(address _asset);\\n event AssetDefaultStrategyUpdated(address _asset, address _strategy);\\n event AssetAllocated(address _asset, address _strategy, uint256 _amount);\\n event StrategyApproved(address _addr);\\n event StrategyRemoved(address _addr);\\n event Mint(address _addr, uint256 _value);\\n event Redeem(address _addr, uint256 _value);\\n event CapitalPaused();\\n event CapitalUnpaused();\\n event RebasePaused();\\n event RebaseUnpaused();\\n event VaultBufferUpdated(uint256 _vaultBuffer);\\n event OusdMetaStrategyUpdated(address _ousdMetaStrategy);\\n event RedeemFeeUpdated(uint256 _redeemFeeBps);\\n event PriceProviderUpdated(address _priceProvider);\\n event AllocateThresholdUpdated(uint256 _threshold);\\n event RebaseThresholdUpdated(uint256 _threshold);\\n event StrategistUpdated(address _address);\\n event MaxSupplyDiffChanged(uint256 maxSupplyDiff);\\n event YieldDistribution(address _to, uint256 _yield, uint256 _fee);\\n event TrusteeFeeBpsChanged(uint256 _basis);\\n event TrusteeAddressChanged(address _address);\\n event NetOusdMintForStrategyThresholdChanged(uint256 _threshold);\\n event SwapperChanged(address _address);\\n event SwapAllowedUndervalueChanged(uint256 _basis);\\n event SwapSlippageChanged(address _asset, uint256 _basis);\\n event Swapped(\\n address indexed _fromAsset,\\n address indexed _toAsset,\\n uint256 _fromAssetAmount,\\n uint256 _toAssetAmount\\n );\\n\\n // Assets supported by the Vault, i.e. Stablecoins\\n enum UnitConversion {\\n DECIMALS,\\n GETEXCHANGERATE\\n }\\n // Changed to fit into a single storage slot so the decimals needs to be recached\\n struct Asset {\\n bool isSupported;\\n UnitConversion unitConversion;\\n uint8 decimals;\\n // Max allowed slippage from the Oracle price when swapping collateral assets in basis points.\\n // For example 40 == 0.4% slippage\\n uint16 allowedOracleSlippageBps;\\n }\\n\\n /// @dev mapping of supported vault assets to their configuration\\n // slither-disable-next-line uninitialized-state\\n mapping(address => Asset) internal assets;\\n /// @dev list of all assets supported by the vault.\\n address[] internal allAssets;\\n\\n // Strategies approved for use by the Vault\\n struct Strategy {\\n bool isSupported;\\n uint256 _deprecated; // Deprecated storage slot\\n }\\n /// @dev mapping of strategy contracts to their configiration\\n mapping(address => Strategy) internal strategies;\\n /// @dev list of all vault strategies\\n address[] internal allStrategies;\\n\\n /// @notice Address of the Oracle price provider contract\\n // slither-disable-next-line uninitialized-state\\n address public priceProvider;\\n /// @notice pause rebasing if true\\n bool public rebasePaused = false;\\n /// @notice pause operations that change the OToken supply.\\n /// eg mint, redeem, allocate, mint/burn for strategy\\n bool public capitalPaused = true;\\n /// @notice Redemption fee in basis points. eg 50 = 0.5%\\n uint256 public redeemFeeBps;\\n /// @notice Percentage of assets to keep in Vault to handle (most) withdrawals. 100% = 1e18.\\n uint256 public vaultBuffer;\\n /// @notice OToken mints over this amount automatically allocate funds. 18 decimals.\\n uint256 public autoAllocateThreshold;\\n /// @notice OToken mints over this amount automatically rebase. 18 decimals.\\n uint256 public rebaseThreshold;\\n\\n /// @dev Address of the OToken token. eg OUSD or OETH.\\n // slither-disable-next-line uninitialized-state\\n OUSD internal oUSD;\\n\\n //keccak256(\\\"OUSD.vault.governor.admin.impl\\\");\\n bytes32 constant adminImplPosition =\\n 0xa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9;\\n\\n // Address of the contract responsible for post rebase syncs with AMMs\\n address private _deprecated_rebaseHooksAddr = address(0);\\n\\n // Deprecated: Address of Uniswap\\n // slither-disable-next-line constable-states\\n address private _deprecated_uniswapAddr = address(0);\\n\\n /// @notice Address of the Strategist\\n address public strategistAddr = address(0);\\n\\n /// @notice Mapping of asset address to the Strategy that they should automatically\\n // be allocated to\\n mapping(address => address) public assetDefaultStrategies;\\n\\n /// @notice Max difference between total supply and total value of assets. 18 decimals.\\n uint256 public maxSupplyDiff;\\n\\n /// @notice Trustee contract that can collect a percentage of yield\\n address public trusteeAddress;\\n\\n /// @notice Amount of yield collected in basis points. eg 2000 = 20%\\n uint256 public trusteeFeeBps;\\n\\n /// @dev Deprecated: Tokens that should be swapped for stablecoins\\n address[] private _deprecated_swapTokens;\\n\\n uint256 constant MINT_MINIMUM_UNIT_PRICE = 0.998e18;\\n\\n /// @notice Metapool strategy that is allowed to mint/burn OTokens without changing collateral\\n address public ousdMetaStrategy = address(0);\\n\\n /// @notice How much OTokens are currently minted by the strategy\\n int256 public netOusdMintedForStrategy = 0;\\n\\n /// @notice How much net total OTokens are allowed to be minted by all strategies\\n uint256 public netOusdMintForStrategyThreshold = 0;\\n\\n uint256 constant MIN_UNIT_PRICE_DRIFT = 0.7e18;\\n uint256 constant MAX_UNIT_PRICE_DRIFT = 1.3e18;\\n\\n /// @notice Collateral swap configuration.\\n /// @dev is packed into a single storage slot to save gas.\\n struct SwapConfig {\\n // Contract that swaps the vault's collateral assets\\n address swapper;\\n // Max allowed percentage the total value can drop below the total supply in basis points.\\n // For example 100 == 1%\\n uint16 allowedUndervalueBps;\\n }\\n SwapConfig internal swapConfig = SwapConfig(address(0), 0);\\n\\n /**\\n * @notice set the implementation for the admin, this needs to be in a base class else we cannot set it\\n * @param newImpl address of the implementation\\n */\\n function setAdminImpl(address newImpl) external onlyGovernor {\\n require(\\n Address.isContract(newImpl),\\n \\\"new implementation is not a contract\\\"\\n );\\n bytes32 position = adminImplPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, newImpl)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x19891574f3b33074486f48166879b4cccc88162c392e77192bd54367ec263287\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6037805461ffff60a01b1916600160a81b179055603d80546001600160a01b0319908116909155603e805482169055603f80548216905560458054909116905560006046819055604781905560e060405260a081905260c052604880546001600160b01b03191690553480156200007557600080fd5b50604051620037a6380380620037a683398101604081905262000098916200010e565b620000b0336000805160206200378683398151915255565b60008051602062003786833981519152546040516001600160a01b03909116906000907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908290a360601b6001600160601b03191660805262000140565b6000602082840312156200012157600080fd5b81516001600160a01b03811681146200013957600080fd5b9392505050565b60805160601c613620620001666000396000818161033901526105f901526136206000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c80636ec3ab671161013b578063abaa9916116100b8578063d38bfff41161007c578063d38bfff414610526578063d4c3eea014610539578063e45cc9f014610541578063e6cc54321461054a578063fc0cfeee1461055e57610248565b8063abaa9916146104f3578063af14052c146104fb578063b888879e14610503578063c3b2886414610516578063c7af33521461051e57610248565b80639be918e6116100ff5780639be918e61461047a5780639fa1826e146104a6578063a0aead4d146104af578063a403e4d5146104b7578063ab80dafb146104e057610248565b80636ec3ab67146104225780637136a7a6146104425780637a2202f3146104555780637cbc23731461045e5780638e510b521461047157610248565b8063485cc955116101c95780635b60f9fc1161018d5780635b60f9fc146103c15780635d36b190146103d45780635f515226146103dc5780636217f3ea146103ef57806367bd7ba31461040257610248565b8063485cc9551461035b57806349c1d54d1461036e57806352d38e5d1461038157806353ca9f241461038a578063570d8e1d146103ae57610248565b8063207134b011610210578063207134b0146102fb5780632acada4d1461030457806331e19cfa146103195780633b8fe28d146103215780633fc8cef31461033457610248565b806309f6442c1461028e5780630c340a24146102aa578063156e29f6146102ca57806318ce56bd146102df5780631edfe3da146102f2575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610289573d6000f35b3d6000fd5b61029760385481565b6040519081526020015b60405180910390f35b6102b2610571565b6040516001600160a01b0390911681526020016102a1565b6102dd6102d8366004613033565b61058e565b005b6045546102b2906001600160a01b031681565b61029760395481565b61029760435481565b61030c61068d565b6040516102a19190613111565b603654610297565b61029761032f366004612fe5565b6106ef565b6102b27f000000000000000000000000000000000000000000000000000000000000000081565b6102dd610369366004613000565b61074a565b6042546102b2906001600160a01b031681565b610297603b5481565b60375461039e90600160a01b900460ff1681565b60405190151581526020016102a1565b603f546102b2906001600160a01b031681565b6102976103cf366004612fe5565b61094c565b6102dd610975565b6102976103ea366004612fe5565b610a1b565b6102dd6103fd366004613088565b610a2c565b610415610410366004613088565b610bc3565b6040516102a1919061315e565b610435610430366004612fe5565b610bce565b6040516102a191906132bd565b6102dd610450366004613088565b610c74565b61029760475481565b6102dd61046c3660046130ba565b610d5f565b61029760415481565b61039e610488366004612fe5565b6001600160a01b031660009081526033602052604090205460ff1690565b610297603a5481565b603454610297565b6102b26104c5366004612fe5565b6040602081905260009182529020546001600160a01b031681565b6102dd6104ee366004613088565b610dd2565b6102dd610f49565b6102dd610fb8565b6037546102b2906001600160a01b031681565b61030c610ffe565b61039e61105e565b6102dd610534366004612fe5565b61108f565b610297611133565b61029760465481565b60375461039e90600160a81b900460ff1681565b6102dd61056c366004612fe5565b61113d565b60006105896000805160206135cb8339815191525490565b905090565b603754600160a81b900460ff16156105c15760405162461bcd60e51b81526004016105b89061326d565b60405180910390fd5b6000805160206135ab833981519152805460028114156105f35760405162461bcd60e51b81526004016105b890613295565b600282557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316146106785760405162461bcd60e51b815260206004820152601d60248201527f556e737570706f7274656420617373657420666f72206d696e74696e6700000060448201526064016105b8565b6106838585856111df565b5060019055505050565b606060348054806020026020016040519081016040528092919081815260200182805480156106e557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106c7575b5050505050905090565b6000806107186107126107018561141e565b670de0b6b3a7640000906012611488565b846114ea565b9050670de0b6b3a76400008161072f856001611646565b6107399190613479565b610743919061336c565b9392505050565b61075261105e565b61076e5760405162461bcd60e51b81526004016105b89061320d565b600054610100900460ff1680610787575060005460ff16155b6107ea5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105b8565b600054610100900460ff1615801561080c576000805461ffff19166101011790555b6001600160a01b0383166108625760405162461bcd60e51b815260206004820152601d60248201527f507269636550726f76696465722061646472657373206973207a65726f00000060448201526064016105b8565b6001600160a01b0382166108b15760405162461bcd60e51b81526020600482015260166024820152756f546f6b656e2061646472657373206973207a65726f60501b60448201526064016105b8565b603c80546001600160a01b038481166001600160a01b031990921691909117909155603780546001600160b01b03191691851691909117600160a81b17905560006038819055603981905569054b40b1f852bda00000603a55683635c9adc5dea00000603b55604080519182526020820190819052905161093491603691612f5d565b508015610947576000805461ff00191690555b505050565b60008061095e6107126107018561141e565b9050670de0b6b3a76400008161072f856000611646565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610a105760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b60648201526084016105b8565b610a1933611938565b565b6000610a26826119fc565b92915050565b603754600160a81b900460ff1615610a565760405162461bcd60e51b81526004016105b89061326d565b6045546001600160a01b03163314610a805760405162461bcd60e51b81526004016105b8906131c9565b6001600160ff1b038110610aa65760405162461bcd60e51b81526004016105b890613244565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63382604051610ad79291906130f8565b60405180910390a18060466000828254610af19190613498565b9091555050604754604654610b0590611bcb565b10610b5c5760405162461bcd60e51b815260206004820152602160248201527f417474656d7074696e6720746f206275726e20746f6f206d756368204f5553446044820152601760f91b60648201526084016105b8565b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610b8e90339085906004016130f8565b600060405180830381600087803b158015610ba857600080fd5b505af1158015610bbc573d6000803e3d6000fd5b5050505050565b6060610a2682611c0e565b604080516080808201835260008083526020808401829052838501829052606084018290526001600160a01b038616825260338152908490208451928301909452835460ff808216151584529394929391840191610100909104166001811115610c3a57610c3a613568565b6001811115610c4b57610c4b613568565b8152905462010000810460ff1660208301526301000000900461ffff1660409091015292915050565b603754600160a81b900460ff1615610c9e5760405162461bcd60e51b81526004016105b89061326d565b6000805160206135ab83398151915280546002811415610cd05760405162461bcd60e51b81526004016105b890613295565b60028255603c546040516370a0823160e01b8152336004820152610d57916001600160a01b0316906370a082319060240160206040518083038186803b158015610d1957600080fd5b505afa158015610d2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5191906130a1565b84611eee565b506001905550565b603754600160a81b900460ff1615610d895760405162461bcd60e51b81526004016105b89061326d565b6000805160206135ab83398151915280546002811415610dbb5760405162461bcd60e51b81526004016105b890613295565b60028255610dc98484611eee565b50600190555050565b603754600160a81b900460ff1615610dfc5760405162461bcd60e51b81526004016105b89061326d565b6045546001600160a01b03163314610e265760405162461bcd60e51b81526004016105b8906131c9565b6001600160ff1b038110610e4c5760405162461bcd60e51b81526004016105b890613244565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853382604051610e7d9291906130f8565b60405180910390a18060466000828254610e979190613313565b9091555050604754604654610eab90611bcb565b10610f175760405162461bcd60e51b815260206004820152603660248201527f4d696e746564206f75736420737572706173736564206e65744f7573644d696e6044820152753a2337b929ba3930ba32b3bcaa343932b9b437b6321760511b60648201526084016105b8565b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610b8e90339085906004016130f8565b603754600160a81b900460ff1615610f735760405162461bcd60e51b81526004016105b89061326d565b6000805160206135ab83398151915280546002811415610fa55760405162461bcd60e51b81526004016105b890613295565b60028255610fb1612418565b5060019055565b6000805160206135ab83398151915280546002811415610fea5760405162461bcd60e51b81526004016105b890613295565b60028255610ff6612684565b505060019055565b606060368054806020026020016040519081016040528092919081815260200182805480156106e5576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116106c7575050505050905090565b60006110766000805160206135cb8339815191525490565b6001600160a01b0316336001600160a01b031614905090565b61109761105e565b6110b35760405162461bcd60e51b81526004016105b89061320d565b6110db817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b03166110fb6000805160206135cb8339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006105896129bf565b61114561105e565b6111615760405162461bcd60e51b81526004016105b89061320d565b803b6111bb5760405162461bcd60e51b8152602060048201526024808201527f6e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e746044820152631c9858dd60e21b60648201526084016105b8565b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b6001600160a01b03831660009081526033602052604090205460ff166112405760405162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b60448201526064016105b8565b600082116112905760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016105b8565b600061129c83856114ea565b905060006112ab856001611646565b90506000670de0b6b3a76400006112c28385613479565b6112cc919061336c565b9050831561132457838110156113245760405162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d000060448201526064016105b8565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688533826040516113559291906130f8565b60405180910390a1603b5481101580156113795750603754600160a01b900460ff16155b1561138857611386612684565b505b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906113ba90339085906004016130f8565b600060405180830381600087803b1580156113d457600080fd5b505af11580156113e8573d6000803e3d6000fd5b508892506114049150506001600160a01b0382163330896129db565b603a54821061141557611415612418565b50505050505050565b6001600160a01b03811660009081526033602052604090205462010000900460ff16806114835760405162461bcd60e51b8152602060048201526013602482015272111958da5b585b1cc81b9bdd0818d858da1959606a1b60448201526064016105b8565b919050565b6000818311156114b8576114b161149f83856134d7565b6114aa90600a6133d1565b8590612a46565b93506114e2565b818310156114e2576114df6114cd84846134d7565b6114d890600a6133d1565b8590612a52565b93505b509192915050565b6001600160a01b038116600090815260336020526040812054610100900460ff168181600181111561151e5761151e613568565b14156115425761153a60126115328561141e565b869190611488565b915050610a26565b600181600181111561155657611556613568565b14156115f7576000836001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561159757600080fd5b505afa1580156115ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cf91906130a1565b9050670de0b6b3a76400006115e48287613479565b6115ee919061336c565b92505050610a26565b60405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105b8565b5092915050565b6001600160a01b038281166000818152603360205260408082205460375491516315d5220f60e31b81526004810194909452919361010090920460ff169291169063aea910789060240160206040518083038186803b1580156116a857600080fd5b505afa1580156116bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e091906130a1565b915060018160018111156116f6576116f6613568565b1415611796576000846001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561173757600080fd5b505afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f91906130a1565b90508061178484670de0b6b3a7640000613479565b61178e919061336c565b9250506117f7565b60008160018111156117aa576117aa613568565b146117f75760405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105b8565b67120a871cc002000082111561184f5760405162461bcd60e51b815260206004820152601860248201527f5661756c743a2050726963652065786365656473206d6178000000000000000060448201526064016105b8565b6709b6e64a8ec600008210156118a05760405162461bcd60e51b81526020600482015260166024820152752b30bab63a1d10283934b1b2903ab73232b91036b4b760511b60448201526064016105b8565b821561191757670de0b6b3a76400008211156118c257670de0b6b3a764000091505b670dd99bb65dd700008210156119125760405162461bcd60e51b815260206004820152601560248201527441737365742070726963652062656c6f772070656760581b60448201526064016105b8565b61163f565b670de0b6b3a764000082101561163f5750670de0b6b3a76400009392505050565b6001600160a01b03811661198e5760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f72206973206164647265737328302900000000000060448201526064016105b8565b806001600160a01b03166119ae6000805160206135cb8339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36119f9816000805160206135cb83398151915255565b50565b6040516370a0823160e01b815230600482015260009082906001600160a01b038216906370a082319060240160206040518083038186803b158015611a4057600080fd5b505afa158015611a54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7891906130a1565b60365490925060005b81811015611bc357600060368281548110611a9e57611a9e61357e565b60009182526020909120015460405163551c457b60e11b81526001600160a01b0388811660048301529091169150819063aa388af69060240160206040518083038186803b158015611aef57600080fd5b505afa158015611b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b279190613066565b15611bb257604051632fa8a91360e11b81526001600160a01b038781166004830152821690635f5152269060240160206040518083038186803b158015611b6d57600080fd5b505afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba591906130a1565b611baf9086613354565b94505b50611bbc8161351a565b9050611a81565b505050919050565b60006001600160ff1b038212611bf35760405162461bcd60e51b81526004016105b890613244565b6000821215611c0a57611c0582613535565b610a26565b5090565b60345460609060008167ffffffffffffffff811115611c2f57611c2f613594565b604051908082528060200260200182016040528015611c58578160200160208202803683370190505b50905060008267ffffffffffffffff811115611c7657611c76613594565b604051908082528060200260200182016040528015611c9f578160200160208202803683370190505b5090508267ffffffffffffffff811115611cbb57611cbb613594565b604051908082528060200260200182016040528015611ce4578160200160208202803683370190505b5060385490945015611d1457603854600090611d04908790612710612a5e565b9050611d1081876134d7565b9550505b6000805b84811015611dd757600060348281548110611d3557611d3561357e565b60009182526020822001546001600160a01b03169150611d54826119fc565b905080858481518110611d6957611d6961357e565b602002602001018181525050611d7f81836114ea565b868481518110611d9157611d9161357e565b602002602001018181525050858381518110611daf57611daf61357e565b602002602001015184611dc29190613354565b9350505080611dd09061351a565b9050611d18565b506000805b85811015611e6b576000611e1660348381548110611dfc57611dfc61357e565b60009182526020822001546001600160a01b031690611646565b905060008482888581518110611e2e57611e2e61357e565b6020026020010151611e409190613479565b611e4a919061336c565b9050611e568185613354565b9350505080611e649061351a565b9050611ddc565b506000611e788883612a80565b905060005b86811015611ee2578382868381518110611e9957611e9961357e565b6020026020010151611eab9190613479565b611eb5919061336c565b888281518110611ec757611ec761357e565b6020908102919091010152611edb8161351a565b9050611e7d565b50505050505050919050565b6000611ef983611c0e565b90507f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63384604051611f2c9291906130f8565b60405180910390a160345460005b8181101561217d57828181518110611f5457611f5461357e565b602002602001015160001415611f695761216d565b600060348281548110611f7e57611f7e61357e565b60009182526020909120015484516001600160a01b039091169150849083908110611fab57611fab61357e565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015611ff557600080fd5b505afa158015612009573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202d91906130a1565b1061206e57612069338584815181106120485761204861357e565b6020026020010151836001600160a01b0316612aa99092919063ffffffff16565b61216b565b6001600160a01b0380821660009081526040602081905290205416801561212f576000819050806001600160a01b031663d9caed1233858988815181106120b7576120b761357e565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561211157600080fd5b505af1158015612125573d6000803e3d6000fd5b5050505050612169565b60405162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b60448201526064016105b8565b505b505b6121768161351a565b9050611f3a565b50821561224a576000805b83518110156121f7576121db8482815181106121a6576121a661357e565b6020026020010151603483815481106121c1576121c161357e565b6000918252602090912001546001600160a01b03166114ea565b6121e59083613354565b91506121f08161351a565b9050612188565b50838110156122485760405162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d60448201526064016105b8565b505b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac9061227c90339088906004016130f8565b600060405180830381600087803b15801561229657600080fd5b505af11580156122aa573d6000803e3d6000fd5b505050506000603b5485101580156122cc5750603754600160a01b900460ff16155b156122e0576122d9612684565b90506122eb565b6122e86129bf565b90505b60415415610bbc57600061238582603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561234757600080fd5b505afa15801561235b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237f91906130a1565b90612a80565b9050604154670de0b6b3a764000082116123b0576123ab82670de0b6b3a76400006134d7565b6123c2565b6123c2670de0b6b3a7640000836134d7565b11156124105760405162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f72000060448201526064016105b8565b505050505050565b6000612422612ac8565b90508061242c5750565b6000612436612baa565b905060006124448284613354565b90506000826124695760395461246290670de0b6b3a76400006134d7565b90506124ac565b83826039546124789190613479565b612482919061336c565b905080670de0b6b3a764000011156124a65761246281670de0b6b3a76400006134d7565b50505050565b806124b75750505050565b60345460005b81811015612410576000603482815481106124da576124da61357e565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b15801561252857600080fd5b505afa15801561253c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256091906130a1565b90508061256e575050612674565b600061257a8287612c06565b6001600160a01b038085166000908152604060208190529020549192501680158015906125a75750600082115b1561266f57806125c16001600160a01b0386168285612aa9565b6040516311f9fbc960e21b81526001600160a01b038216906347e7ef24906125ef90889087906004016130f8565b600060405180830381600087803b15801561260957600080fd5b505af115801561261d573d6000803e3d6000fd5b5050604080516001600160a01b03808a168252861660208201529081018690527f41b99659f6ba0803f444aff29e5bf6e26dd86a3219aff92119d69710a956ba8d9250606001905060405180910390a1505b505050505b61267d8161351a565b90506124bd565b603754600090600160a01b900460ff16156126d35760405162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b60448201526064016105b8565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561271857600080fd5b505afa15801561272c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275091906130a1565b9050600061275c6129bf565b90508161276c5791506129bc9050565b6042546001600160a01b0316801580159061278657508282115b156128c857600061279784846134d7565b905060006127b460435461271084612a5e9092919063ffffffff16565b90508082116128105760405162461bcd60e51b815260206004820152602260248201527f466565206d757374206e6f742062652067726561746572207468616e207969656044820152611b1960f21b60648201526084016105b8565b801561287b57603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f199061284890869085906004016130f8565b600060405180830381600087803b15801561286257600080fd5b505af1158015612876573d6000803e3d6000fd5b505050505b604080516001600160a01b0385168152602081018490529081018290527f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809060600160405180910390a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561291657600080fd5b505afa15801561292a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294e91906130a1565b9250828211156129b757603c546040516339a7919f60e01b8152600481018490526001600160a01b03909116906339a7919f90602401600060405180830381600087803b15801561299e57600080fd5b505af11580156129b2573d6000803e3d6000fd5b505050505b509150505b90565b60006129c9612baa565b6129d1612ac8565b6105899190613354565b6040516001600160a01b03808516602483015283166044820152606481018290526124a69085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c1b565b60006107438284613479565b6000610743828461336c565b600080612a6b8585612a46565b9050612a778184612a52565b95945050505050565b600080612a9584670de0b6b3a7640000612a46565b9050612aa18184612a52565b949350505050565b6109478363a9059cbb60e01b8484604051602401612a0f9291906130f8565b603454600090815b81811015612ba557600060348281548110612aed57612aed61357e565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b158015612b3b57600080fd5b505afa158015612b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7391906130a1565b90508015612b9257612b8581836114ea565b612b8f9086613354565b94505b505080612b9e9061351a565b9050612ad0565b505090565b603654600090815b81811015612ba557612bea60368281548110612bd057612bd061357e565b6000918252602090912001546001600160a01b0316612ced565b612bf49084613354565b9250612bff8161351a565b9050612bb2565b60006107438383670de0b6b3a7640000612a5e565b6000612c70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e529092919063ffffffff16565b8051909150156109475780806020019051810190612c8e9190613066565b6109475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105b8565b6034546000908290825b81811015611bc357600060348281548110612d1457612d1461357e565b60009182526020909120015460405163551c457b60e11b81526001600160a01b039182166004820181905292509085169063aa388af69060240160206040518083038186803b158015612d6657600080fd5b505afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190613066565b15612e4157604051632fa8a91360e11b81526001600160a01b03828116600483015260009190861690635f5152269060240160206040518083038186803b158015612de857600080fd5b505afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2091906130a1565b90508015612e3f57612e3281836114ea565b612e3c9087613354565b95505b505b50612e4b8161351a565b9050612cf7565b6060612aa1848460008585843b612eab5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105b8565b600080866001600160a01b03168587604051612ec791906130dc565b60006040518083038185875af1925050503d8060008114612f04576040519150601f19603f3d011682016040523d82523d6000602084013e612f09565b606091505b5091509150612f19828286612f24565b979650505050505050565b60608315612f33575081610743565b825115612f435782518084602001fd5b8160405162461bcd60e51b81526004016105b89190613196565b828054828255906000526020600020908101928215612fb2579160200282015b82811115612fb257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612f7d565b50611c0a9291505b80821115611c0a5760008155600101612fba565b80356001600160a01b038116811461148357600080fd5b600060208284031215612ff757600080fd5b61074382612fce565b6000806040838503121561301357600080fd5b61301c83612fce565b915061302a60208401612fce565b90509250929050565b60008060006060848603121561304857600080fd5b61305184612fce565b95602085013595506040909401359392505050565b60006020828403121561307857600080fd5b8151801515811461074357600080fd5b60006020828403121561309a57600080fd5b5035919050565b6000602082840312156130b357600080fd5b5051919050565b600080604083850312156130cd57600080fd5b50508035926020909101359150565b600082516130ee8184602087016134ee565b9190910192915050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156131525783516001600160a01b03168352928401929184019160010161312d565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156131525783518352928401929184019160010161317a565b60208152600082518060208401526131b58160408501602087016134ee565b601f01601f19169190910160400192915050565b60208082526024908201527f43616c6c6572206973206e6f7420746865204f555344206d65746120737472616040820152637465677960e01b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252600f908201526e082dadeeadce840e8dede40d0d2ced608b1b604082015260600190565b6020808252600e908201526d10d85c1a5d185b081c185d5cd95960921b604082015260600190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b81511515815260208201516080820190600281106132eb57634e487b7160e01b600052602160045260246000fd5b8060208401525060ff604084015116604083015261ffff606084015116606083015292915050565b600080821280156001600160ff1b038490038513161561333557613335613552565b600160ff1b839003841281161561334e5761334e613552565b50500190565b6000821982111561336757613367613552565b500190565b60008261338957634e487b7160e01b600052601260045260246000fd5b500490565b600181815b808511156133c95781600019048211156133af576133af613552565b808516156133bc57918102915b93841c9390800290613393565b509250929050565b600061074383836000826133e757506001610a26565b816133f457506000610a26565b816001811461340a576002811461341457613430565b6001915050610a26565b60ff84111561342557613425613552565b50506001821b610a26565b5060208310610133831016604e8410600b8410161715613453575081810a610a26565b61345d838361338e565b806000190482111561347157613471613552565b029392505050565b600081600019048311821515161561349357613493613552565b500290565b60008083128015600160ff1b8501841216156134b6576134b6613552565b6001600160ff1b03840183138116156134d1576134d1613552565b50500390565b6000828210156134e9576134e9613552565b500390565b60005b838110156135095781810151838201526020016134f1565b838111156124a65750506000910152565b600060001982141561352e5761352e613552565b5060010190565b6000600160ff1b82141561354b5761354b613552565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220aae212cbb50b4746647e5105cc3fcd87a8ff6bf2994c81cb3e89a0ce569d22c364736f6c634300080700337bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c80636ec3ab671161013b578063abaa9916116100b8578063d38bfff41161007c578063d38bfff414610526578063d4c3eea014610539578063e45cc9f014610541578063e6cc54321461054a578063fc0cfeee1461055e57610248565b8063abaa9916146104f3578063af14052c146104fb578063b888879e14610503578063c3b2886414610516578063c7af33521461051e57610248565b80639be918e6116100ff5780639be918e61461047a5780639fa1826e146104a6578063a0aead4d146104af578063a403e4d5146104b7578063ab80dafb146104e057610248565b80636ec3ab67146104225780637136a7a6146104425780637a2202f3146104555780637cbc23731461045e5780638e510b521461047157610248565b8063485cc955116101c95780635b60f9fc1161018d5780635b60f9fc146103c15780635d36b190146103d45780635f515226146103dc5780636217f3ea146103ef57806367bd7ba31461040257610248565b8063485cc9551461035b57806349c1d54d1461036e57806352d38e5d1461038157806353ca9f241461038a578063570d8e1d146103ae57610248565b8063207134b011610210578063207134b0146102fb5780632acada4d1461030457806331e19cfa146103195780633b8fe28d146103215780633fc8cef31461033457610248565b806309f6442c1461028e5780630c340a24146102aa578063156e29f6146102ca57806318ce56bd146102df5780631edfe3da146102f2575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610289573d6000f35b3d6000fd5b61029760385481565b6040519081526020015b60405180910390f35b6102b2610571565b6040516001600160a01b0390911681526020016102a1565b6102dd6102d8366004613033565b61058e565b005b6045546102b2906001600160a01b031681565b61029760395481565b61029760435481565b61030c61068d565b6040516102a19190613111565b603654610297565b61029761032f366004612fe5565b6106ef565b6102b27f000000000000000000000000000000000000000000000000000000000000000081565b6102dd610369366004613000565b61074a565b6042546102b2906001600160a01b031681565b610297603b5481565b60375461039e90600160a01b900460ff1681565b60405190151581526020016102a1565b603f546102b2906001600160a01b031681565b6102976103cf366004612fe5565b61094c565b6102dd610975565b6102976103ea366004612fe5565b610a1b565b6102dd6103fd366004613088565b610a2c565b610415610410366004613088565b610bc3565b6040516102a1919061315e565b610435610430366004612fe5565b610bce565b6040516102a191906132bd565b6102dd610450366004613088565b610c74565b61029760475481565b6102dd61046c3660046130ba565b610d5f565b61029760415481565b61039e610488366004612fe5565b6001600160a01b031660009081526033602052604090205460ff1690565b610297603a5481565b603454610297565b6102b26104c5366004612fe5565b6040602081905260009182529020546001600160a01b031681565b6102dd6104ee366004613088565b610dd2565b6102dd610f49565b6102dd610fb8565b6037546102b2906001600160a01b031681565b61030c610ffe565b61039e61105e565b6102dd610534366004612fe5565b61108f565b610297611133565b61029760465481565b60375461039e90600160a81b900460ff1681565b6102dd61056c366004612fe5565b61113d565b60006105896000805160206135cb8339815191525490565b905090565b603754600160a81b900460ff16156105c15760405162461bcd60e51b81526004016105b89061326d565b60405180910390fd5b6000805160206135ab833981519152805460028114156105f35760405162461bcd60e51b81526004016105b890613295565b600282557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316146106785760405162461bcd60e51b815260206004820152601d60248201527f556e737570706f7274656420617373657420666f72206d696e74696e6700000060448201526064016105b8565b6106838585856111df565b5060019055505050565b606060348054806020026020016040519081016040528092919081815260200182805480156106e557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116106c7575b5050505050905090565b6000806107186107126107018561141e565b670de0b6b3a7640000906012611488565b846114ea565b9050670de0b6b3a76400008161072f856001611646565b6107399190613479565b610743919061336c565b9392505050565b61075261105e565b61076e5760405162461bcd60e51b81526004016105b89061320d565b600054610100900460ff1680610787575060005460ff16155b6107ea5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105b8565b600054610100900460ff1615801561080c576000805461ffff19166101011790555b6001600160a01b0383166108625760405162461bcd60e51b815260206004820152601d60248201527f507269636550726f76696465722061646472657373206973207a65726f00000060448201526064016105b8565b6001600160a01b0382166108b15760405162461bcd60e51b81526020600482015260166024820152756f546f6b656e2061646472657373206973207a65726f60501b60448201526064016105b8565b603c80546001600160a01b038481166001600160a01b031990921691909117909155603780546001600160b01b03191691851691909117600160a81b17905560006038819055603981905569054b40b1f852bda00000603a55683635c9adc5dea00000603b55604080519182526020820190819052905161093491603691612f5d565b508015610947576000805461ff00191690555b505050565b60008061095e6107126107018561141e565b9050670de0b6b3a76400008161072f856000611646565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610a105760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b60648201526084016105b8565b610a1933611938565b565b6000610a26826119fc565b92915050565b603754600160a81b900460ff1615610a565760405162461bcd60e51b81526004016105b89061326d565b6045546001600160a01b03163314610a805760405162461bcd60e51b81526004016105b8906131c9565b6001600160ff1b038110610aa65760405162461bcd60e51b81526004016105b890613244565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63382604051610ad79291906130f8565b60405180910390a18060466000828254610af19190613498565b9091555050604754604654610b0590611bcb565b10610b5c5760405162461bcd60e51b815260206004820152602160248201527f417474656d7074696e6720746f206275726e20746f6f206d756368204f5553446044820152601760f91b60648201526084016105b8565b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610b8e90339085906004016130f8565b600060405180830381600087803b158015610ba857600080fd5b505af1158015610bbc573d6000803e3d6000fd5b5050505050565b6060610a2682611c0e565b604080516080808201835260008083526020808401829052838501829052606084018290526001600160a01b038616825260338152908490208451928301909452835460ff808216151584529394929391840191610100909104166001811115610c3a57610c3a613568565b6001811115610c4b57610c4b613568565b8152905462010000810460ff1660208301526301000000900461ffff1660409091015292915050565b603754600160a81b900460ff1615610c9e5760405162461bcd60e51b81526004016105b89061326d565b6000805160206135ab83398151915280546002811415610cd05760405162461bcd60e51b81526004016105b890613295565b60028255603c546040516370a0823160e01b8152336004820152610d57916001600160a01b0316906370a082319060240160206040518083038186803b158015610d1957600080fd5b505afa158015610d2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5191906130a1565b84611eee565b506001905550565b603754600160a81b900460ff1615610d895760405162461bcd60e51b81526004016105b89061326d565b6000805160206135ab83398151915280546002811415610dbb5760405162461bcd60e51b81526004016105b890613295565b60028255610dc98484611eee565b50600190555050565b603754600160a81b900460ff1615610dfc5760405162461bcd60e51b81526004016105b89061326d565b6045546001600160a01b03163314610e265760405162461bcd60e51b81526004016105b8906131c9565b6001600160ff1b038110610e4c5760405162461bcd60e51b81526004016105b890613244565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853382604051610e7d9291906130f8565b60405180910390a18060466000828254610e979190613313565b9091555050604754604654610eab90611bcb565b10610f175760405162461bcd60e51b815260206004820152603660248201527f4d696e746564206f75736420737572706173736564206e65744f7573644d696e6044820152753a2337b929ba3930ba32b3bcaa343932b9b437b6321760511b60648201526084016105b8565b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610b8e90339085906004016130f8565b603754600160a81b900460ff1615610f735760405162461bcd60e51b81526004016105b89061326d565b6000805160206135ab83398151915280546002811415610fa55760405162461bcd60e51b81526004016105b890613295565b60028255610fb1612418565b5060019055565b6000805160206135ab83398151915280546002811415610fea5760405162461bcd60e51b81526004016105b890613295565b60028255610ff6612684565b505060019055565b606060368054806020026020016040519081016040528092919081815260200182805480156106e5576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116106c7575050505050905090565b60006110766000805160206135cb8339815191525490565b6001600160a01b0316336001600160a01b031614905090565b61109761105e565b6110b35760405162461bcd60e51b81526004016105b89061320d565b6110db817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b03166110fb6000805160206135cb8339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006105896129bf565b61114561105e565b6111615760405162461bcd60e51b81526004016105b89061320d565b803b6111bb5760405162461bcd60e51b8152602060048201526024808201527f6e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e746044820152631c9858dd60e21b60648201526084016105b8565b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b6001600160a01b03831660009081526033602052604090205460ff166112405760405162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b60448201526064016105b8565b600082116112905760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016105b8565b600061129c83856114ea565b905060006112ab856001611646565b90506000670de0b6b3a76400006112c28385613479565b6112cc919061336c565b9050831561132457838110156113245760405162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d000060448201526064016105b8565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688533826040516113559291906130f8565b60405180910390a1603b5481101580156113795750603754600160a01b900460ff16155b1561138857611386612684565b505b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906113ba90339085906004016130f8565b600060405180830381600087803b1580156113d457600080fd5b505af11580156113e8573d6000803e3d6000fd5b508892506114049150506001600160a01b0382163330896129db565b603a54821061141557611415612418565b50505050505050565b6001600160a01b03811660009081526033602052604090205462010000900460ff16806114835760405162461bcd60e51b8152602060048201526013602482015272111958da5b585b1cc81b9bdd0818d858da1959606a1b60448201526064016105b8565b919050565b6000818311156114b8576114b161149f83856134d7565b6114aa90600a6133d1565b8590612a46565b93506114e2565b818310156114e2576114df6114cd84846134d7565b6114d890600a6133d1565b8590612a52565b93505b509192915050565b6001600160a01b038116600090815260336020526040812054610100900460ff168181600181111561151e5761151e613568565b14156115425761153a60126115328561141e565b869190611488565b915050610a26565b600181600181111561155657611556613568565b14156115f7576000836001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561159757600080fd5b505afa1580156115ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cf91906130a1565b9050670de0b6b3a76400006115e48287613479565b6115ee919061336c565b92505050610a26565b60405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105b8565b5092915050565b6001600160a01b038281166000818152603360205260408082205460375491516315d5220f60e31b81526004810194909452919361010090920460ff169291169063aea910789060240160206040518083038186803b1580156116a857600080fd5b505afa1580156116bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e091906130a1565b915060018160018111156116f6576116f6613568565b1415611796576000846001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561173757600080fd5b505afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f91906130a1565b90508061178484670de0b6b3a7640000613479565b61178e919061336c565b9250506117f7565b60008160018111156117aa576117aa613568565b146117f75760405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105b8565b67120a871cc002000082111561184f5760405162461bcd60e51b815260206004820152601860248201527f5661756c743a2050726963652065786365656473206d6178000000000000000060448201526064016105b8565b6709b6e64a8ec600008210156118a05760405162461bcd60e51b81526020600482015260166024820152752b30bab63a1d10283934b1b2903ab73232b91036b4b760511b60448201526064016105b8565b821561191757670de0b6b3a76400008211156118c257670de0b6b3a764000091505b670dd99bb65dd700008210156119125760405162461bcd60e51b815260206004820152601560248201527441737365742070726963652062656c6f772070656760581b60448201526064016105b8565b61163f565b670de0b6b3a764000082101561163f5750670de0b6b3a76400009392505050565b6001600160a01b03811661198e5760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f72206973206164647265737328302900000000000060448201526064016105b8565b806001600160a01b03166119ae6000805160206135cb8339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36119f9816000805160206135cb83398151915255565b50565b6040516370a0823160e01b815230600482015260009082906001600160a01b038216906370a082319060240160206040518083038186803b158015611a4057600080fd5b505afa158015611a54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7891906130a1565b60365490925060005b81811015611bc357600060368281548110611a9e57611a9e61357e565b60009182526020909120015460405163551c457b60e11b81526001600160a01b0388811660048301529091169150819063aa388af69060240160206040518083038186803b158015611aef57600080fd5b505afa158015611b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b279190613066565b15611bb257604051632fa8a91360e11b81526001600160a01b038781166004830152821690635f5152269060240160206040518083038186803b158015611b6d57600080fd5b505afa158015611b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba591906130a1565b611baf9086613354565b94505b50611bbc8161351a565b9050611a81565b505050919050565b60006001600160ff1b038212611bf35760405162461bcd60e51b81526004016105b890613244565b6000821215611c0a57611c0582613535565b610a26565b5090565b60345460609060008167ffffffffffffffff811115611c2f57611c2f613594565b604051908082528060200260200182016040528015611c58578160200160208202803683370190505b50905060008267ffffffffffffffff811115611c7657611c76613594565b604051908082528060200260200182016040528015611c9f578160200160208202803683370190505b5090508267ffffffffffffffff811115611cbb57611cbb613594565b604051908082528060200260200182016040528015611ce4578160200160208202803683370190505b5060385490945015611d1457603854600090611d04908790612710612a5e565b9050611d1081876134d7565b9550505b6000805b84811015611dd757600060348281548110611d3557611d3561357e565b60009182526020822001546001600160a01b03169150611d54826119fc565b905080858481518110611d6957611d6961357e565b602002602001018181525050611d7f81836114ea565b868481518110611d9157611d9161357e565b602002602001018181525050858381518110611daf57611daf61357e565b602002602001015184611dc29190613354565b9350505080611dd09061351a565b9050611d18565b506000805b85811015611e6b576000611e1660348381548110611dfc57611dfc61357e565b60009182526020822001546001600160a01b031690611646565b905060008482888581518110611e2e57611e2e61357e565b6020026020010151611e409190613479565b611e4a919061336c565b9050611e568185613354565b9350505080611e649061351a565b9050611ddc565b506000611e788883612a80565b905060005b86811015611ee2578382868381518110611e9957611e9961357e565b6020026020010151611eab9190613479565b611eb5919061336c565b888281518110611ec757611ec761357e565b6020908102919091010152611edb8161351a565b9050611e7d565b50505050505050919050565b6000611ef983611c0e565b90507f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63384604051611f2c9291906130f8565b60405180910390a160345460005b8181101561217d57828181518110611f5457611f5461357e565b602002602001015160001415611f695761216d565b600060348281548110611f7e57611f7e61357e565b60009182526020909120015484516001600160a01b039091169150849083908110611fab57611fab61357e565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015611ff557600080fd5b505afa158015612009573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202d91906130a1565b1061206e57612069338584815181106120485761204861357e565b6020026020010151836001600160a01b0316612aa99092919063ffffffff16565b61216b565b6001600160a01b0380821660009081526040602081905290205416801561212f576000819050806001600160a01b031663d9caed1233858988815181106120b7576120b761357e565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561211157600080fd5b505af1158015612125573d6000803e3d6000fd5b5050505050612169565b60405162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b60448201526064016105b8565b505b505b6121768161351a565b9050611f3a565b50821561224a576000805b83518110156121f7576121db8482815181106121a6576121a661357e565b6020026020010151603483815481106121c1576121c161357e565b6000918252602090912001546001600160a01b03166114ea565b6121e59083613354565b91506121f08161351a565b9050612188565b50838110156122485760405162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d60448201526064016105b8565b505b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac9061227c90339088906004016130f8565b600060405180830381600087803b15801561229657600080fd5b505af11580156122aa573d6000803e3d6000fd5b505050506000603b5485101580156122cc5750603754600160a01b900460ff16155b156122e0576122d9612684565b90506122eb565b6122e86129bf565b90505b60415415610bbc57600061238582603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561234757600080fd5b505afa15801561235b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237f91906130a1565b90612a80565b9050604154670de0b6b3a764000082116123b0576123ab82670de0b6b3a76400006134d7565b6123c2565b6123c2670de0b6b3a7640000836134d7565b11156124105760405162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f72000060448201526064016105b8565b505050505050565b6000612422612ac8565b90508061242c5750565b6000612436612baa565b905060006124448284613354565b90506000826124695760395461246290670de0b6b3a76400006134d7565b90506124ac565b83826039546124789190613479565b612482919061336c565b905080670de0b6b3a764000011156124a65761246281670de0b6b3a76400006134d7565b50505050565b806124b75750505050565b60345460005b81811015612410576000603482815481106124da576124da61357e565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b15801561252857600080fd5b505afa15801561253c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256091906130a1565b90508061256e575050612674565b600061257a8287612c06565b6001600160a01b038085166000908152604060208190529020549192501680158015906125a75750600082115b1561266f57806125c16001600160a01b0386168285612aa9565b6040516311f9fbc960e21b81526001600160a01b038216906347e7ef24906125ef90889087906004016130f8565b600060405180830381600087803b15801561260957600080fd5b505af115801561261d573d6000803e3d6000fd5b5050604080516001600160a01b03808a168252861660208201529081018690527f41b99659f6ba0803f444aff29e5bf6e26dd86a3219aff92119d69710a956ba8d9250606001905060405180910390a1505b505050505b61267d8161351a565b90506124bd565b603754600090600160a01b900460ff16156126d35760405162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b60448201526064016105b8565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561271857600080fd5b505afa15801561272c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275091906130a1565b9050600061275c6129bf565b90508161276c5791506129bc9050565b6042546001600160a01b0316801580159061278657508282115b156128c857600061279784846134d7565b905060006127b460435461271084612a5e9092919063ffffffff16565b90508082116128105760405162461bcd60e51b815260206004820152602260248201527f466565206d757374206e6f742062652067726561746572207468616e207969656044820152611b1960f21b60648201526084016105b8565b801561287b57603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f199061284890869085906004016130f8565b600060405180830381600087803b15801561286257600080fd5b505af1158015612876573d6000803e3d6000fd5b505050505b604080516001600160a01b0385168152602081018490529081018290527f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809060600160405180910390a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561291657600080fd5b505afa15801561292a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294e91906130a1565b9250828211156129b757603c546040516339a7919f60e01b8152600481018490526001600160a01b03909116906339a7919f90602401600060405180830381600087803b15801561299e57600080fd5b505af11580156129b2573d6000803e3d6000fd5b505050505b509150505b90565b60006129c9612baa565b6129d1612ac8565b6105899190613354565b6040516001600160a01b03808516602483015283166044820152606481018290526124a69085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612c1b565b60006107438284613479565b6000610743828461336c565b600080612a6b8585612a46565b9050612a778184612a52565b95945050505050565b600080612a9584670de0b6b3a7640000612a46565b9050612aa18184612a52565b949350505050565b6109478363a9059cbb60e01b8484604051602401612a0f9291906130f8565b603454600090815b81811015612ba557600060348281548110612aed57612aed61357e565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b158015612b3b57600080fd5b505afa158015612b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7391906130a1565b90508015612b9257612b8581836114ea565b612b8f9086613354565b94505b505080612b9e9061351a565b9050612ad0565b505090565b603654600090815b81811015612ba557612bea60368281548110612bd057612bd061357e565b6000918252602090912001546001600160a01b0316612ced565b612bf49084613354565b9250612bff8161351a565b9050612bb2565b60006107438383670de0b6b3a7640000612a5e565b6000612c70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e529092919063ffffffff16565b8051909150156109475780806020019051810190612c8e9190613066565b6109475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105b8565b6034546000908290825b81811015611bc357600060348281548110612d1457612d1461357e565b60009182526020909120015460405163551c457b60e11b81526001600160a01b039182166004820181905292509085169063aa388af69060240160206040518083038186803b158015612d6657600080fd5b505afa158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e9190613066565b15612e4157604051632fa8a91360e11b81526001600160a01b03828116600483015260009190861690635f5152269060240160206040518083038186803b158015612de857600080fd5b505afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2091906130a1565b90508015612e3f57612e3281836114ea565b612e3c9087613354565b95505b505b50612e4b8161351a565b9050612cf7565b6060612aa1848460008585843b612eab5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105b8565b600080866001600160a01b03168587604051612ec791906130dc565b60006040518083038185875af1925050503d8060008114612f04576040519150601f19603f3d011682016040523d82523d6000602084013e612f09565b606091505b5091509150612f19828286612f24565b979650505050505050565b60608315612f33575081610743565b825115612f435782518084602001fd5b8160405162461bcd60e51b81526004016105b89190613196565b828054828255906000526020600020908101928215612fb2579160200282015b82811115612fb257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612f7d565b50611c0a9291505b80821115611c0a5760008155600101612fba565b80356001600160a01b038116811461148357600080fd5b600060208284031215612ff757600080fd5b61074382612fce565b6000806040838503121561301357600080fd5b61301c83612fce565b915061302a60208401612fce565b90509250929050565b60008060006060848603121561304857600080fd5b61305184612fce565b95602085013595506040909401359392505050565b60006020828403121561307857600080fd5b8151801515811461074357600080fd5b60006020828403121561309a57600080fd5b5035919050565b6000602082840312156130b357600080fd5b5051919050565b600080604083850312156130cd57600080fd5b50508035926020909101359150565b600082516130ee8184602087016134ee565b9190910192915050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156131525783516001600160a01b03168352928401929184019160010161312d565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156131525783518352928401929184019160010161317a565b60208152600082518060208401526131b58160408501602087016134ee565b601f01601f19169190910160400192915050565b60208082526024908201527f43616c6c6572206973206e6f7420746865204f555344206d65746120737472616040820152637465677960e01b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252600f908201526e082dadeeadce840e8dede40d0d2ced608b1b604082015260600190565b6020808252600e908201526d10d85c1a5d185b081c185d5cd95960921b604082015260600190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b81511515815260208201516080820190600281106132eb57634e487b7160e01b600052602160045260246000fd5b8060208401525060ff604084015116604083015261ffff606084015116606083015292915050565b600080821280156001600160ff1b038490038513161561333557613335613552565b600160ff1b839003841281161561334e5761334e613552565b50500190565b6000821982111561336757613367613552565b500190565b60008261338957634e487b7160e01b600052601260045260246000fd5b500490565b600181815b808511156133c95781600019048211156133af576133af613552565b808516156133bc57918102915b93841c9390800290613393565b509250929050565b600061074383836000826133e757506001610a26565b816133f457506000610a26565b816001811461340a576002811461341457613430565b6001915050610a26565b60ff84111561342557613425613552565b50506001821b610a26565b5060208310610133831016604e8410600b8410161715613453575081810a610a26565b61345d838361338e565b806000190482111561347157613471613552565b029392505050565b600081600019048311821515161561349357613493613552565b500290565b60008083128015600160ff1b8501841216156134b6576134b6613552565b6001600160ff1b03840183138116156134d1576134d1613552565b50500390565b6000828210156134e9576134e9613552565b500390565b60005b838110156135095781810151838201526020016134f1565b838111156124a65750506000910152565b600060001982141561352e5761352e613552565b5060010190565b6000600160ff1b82141561354b5761354b613552565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220aae212cbb50b4746647e5105cc3fcd87a8ff6bf2994c81cb3e89a0ce569d22c364736f6c63430008070033", + "numDeployments": 4, + "solcInputHash": "05cf63bc9d16fec1f151da41d46c6e16", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"AllocateThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"AssetAllocated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"}],\"name\":\"AssetDefaultStrategyUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"AssetSupported\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"GovernorshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupplyDiff\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyDiffChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"NetOusdMintForStrategyThresholdChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_ousdMetaStrategy\",\"type\":\"address\"}],\"name\":\"OusdMetaStrategyUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"PendingGovernorshipTransfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_priceProvider\",\"type\":\"address\"}],\"name\":\"PriceProviderUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebasePaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"RebaseThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebaseUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Redeem\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_redeemFeeBps\",\"type\":\"uint256\"}],\"name\":\"RedeemFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"StrategistUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"StrategyApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"}],\"name\":\"StrategyRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"SwapAllowedUndervalueChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"SwapSlippageChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_fromAsset\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_toAsset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fromAssetAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_toAssetAmount\",\"type\":\"uint256\"}],\"name\":\"Swapped\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"SwapperChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"TrusteeAddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"TrusteeFeeBpsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vaultBuffer\",\"type\":\"uint256\"}],\"name\":\"VaultBufferUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_yield\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"YieldDistribution\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"allocate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetDefaultStrategies\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"autoAllocateThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"burnForStrategy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"cacheWETHAssetIndex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedeemOutputs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"capitalPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"checkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAssets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllStrategies\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"getAssetConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"},{\"internalType\":\"enum VaultStorage.UnitConversion\",\"name\":\"unitConversion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"allowedOracleSlippageBps\",\"type\":\"uint16\"}],\"internalType\":\"struct VaultStorage.Asset\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAssetCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStrategyCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_priceProvider\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_oToken\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isGovernor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"isSupportedAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupplyDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"mintForStrategy\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"netOusdMintForStrategyThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"netOusdMintedForStrategy\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ousdMetaStrategy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"priceProvider\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"priceUnitMint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"priceUnitRedeem\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebase\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebasePaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rebaseThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeemAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redeemFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImpl\",\"type\":\"address\"}],\"name\":\"setAdminImpl\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"strategistAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"transferGovernance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trusteeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trusteeFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vaultBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"weth\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wethAssetIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Origin Protocol Inc\",\"kind\":\"dev\",\"methods\":{\"burnForStrategy(uint256)\":{\"details\":\"Notice: can't use `nonReentrant` modifier since the `redeem` function could require withdrawal on `ConvexOUSDMetaStrategy` and that one can call `burnForStrategy` while the execution of the `redeem` has not yet completed -> causing a `nonReentrant` collision. Also important to understand is that this is a limitation imposed by the test suite. Production / mainnet contracts should never be configured in a way where mint/redeem functions that are moving funds between the Vault and end user wallets can influence strategies utilizing this function.\",\"params\":{\"_amount\":\"Amount of OUSD to burn\"}},\"cacheWETHAssetIndex()\":{\"details\":\"Caches WETH's index in `allAssets` variable. Reduces gas usage by redeem by caching that.\"},\"checkBalance(address)\":{\"params\":{\"_asset\":\"Address of asset\"},\"returns\":{\"_0\":\"uint256 Balance of asset in decimals of asset\"}},\"isSupportedAsset(address)\":{\"params\":{\"_asset\":\"address of the asset\"},\"returns\":{\"_0\":\"true if supported\"}},\"mint(address,uint256,uint256)\":{\"params\":{\"_amount\":\"Amount of the asset being deposited\",\"_asset\":\"Address of the asset being deposited\",\"_minimumOusdAmount\":\"Minimum OTokens to mint\"}},\"mintForStrategy(uint256)\":{\"params\":{\"_amount\":\"Amount of the asset being deposited Notice: can't use `nonReentrant` modifier since the `mint` function can call `allocate`, and that can trigger `ConvexOUSDMetaStrategy` to call this function while the execution of the `mint` has not yet completed -> causing a `nonReentrant` collision. Also important to understand is that this is a limitation imposed by the test suite. Production / mainnet contracts should never be configured in a way where mint/redeem functions that are moving funds between the Vault and end user wallets can influence strategies utilizing this function.\"}},\"priceUnitMint(address)\":{\"params\":{\"asset\":\"address of the asset\"},\"returns\":{\"price\":\"uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\"}},\"priceUnitRedeem(address)\":{\"params\":{\"asset\":\"Address of the asset\"},\"returns\":{\"price\":\"uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\"}},\"redeem(uint256,uint256)\":{\"params\":{\"_amount\":\"Amount of OTokens to burn\",\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"redeemAll(uint256)\":{\"params\":{\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"setAdminImpl(address)\":{\"params\":{\"newImpl\":\"address of the implementation\"}},\"totalValue()\":{\"returns\":{\"value\":\"Total value in USD/ETH (1e18)\"}},\"transferGovernance(address)\":{\"params\":{\"_newGovernor\":\"Address of the new Governor\"}}},\"title\":\"OETH VaultCore Contract\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"allocate()\":{\"notice\":\"Allocate unallocated funds on Vault to strategies.*\"},\"assetDefaultStrategies(address)\":{\"notice\":\"Mapping of asset address to the Strategy that they should automatically\"},\"autoAllocateThreshold()\":{\"notice\":\"OToken mints over this amount automatically allocate funds. 18 decimals.\"},\"burnForStrategy(uint256)\":{\"notice\":\"Burn OTokens for Metapool Strategy\"},\"calculateRedeemOutputs(uint256)\":{\"notice\":\"Calculate the outputs for a redeem function, i.e. the mix of coins that will be returned\"},\"capitalPaused()\":{\"notice\":\"pause operations that change the OToken supply. eg mint, redeem, allocate, mint/burn for strategy\"},\"checkBalance(address)\":{\"notice\":\"Get the balance of an asset held in Vault and all strategies.\"},\"claimGovernance()\":{\"notice\":\"Claim Governance of the contract to a new account (`newGovernor`). Can only be called by the new Governor.\"},\"getAllAssets()\":{\"notice\":\"Return all vault asset addresses in order\"},\"getAllStrategies()\":{\"notice\":\"Return the array of all strategies\"},\"getAssetConfig(address)\":{\"notice\":\"Gets the vault configuration of a supported asset.\"},\"getAssetCount()\":{\"notice\":\"Return the number of assets supported by the Vault.\"},\"getStrategyCount()\":{\"notice\":\"Return the number of strategies active on the Vault.\"},\"governor()\":{\"notice\":\"Returns the address of the current Governor.\"},\"isGovernor()\":{\"notice\":\"Returns true if the caller is the current Governor.\"},\"isSupportedAsset(address)\":{\"notice\":\"Returns whether the vault supports the asset\"},\"maxSupplyDiff()\":{\"notice\":\"Max difference between total supply and total value of assets. 18 decimals.\"},\"mint(address,uint256,uint256)\":{\"notice\":\"Deposit a supported asset and mint OTokens.\"},\"mintForStrategy(uint256)\":{\"notice\":\"Mint OTokens for a Metapool Strategy\"},\"netOusdMintForStrategyThreshold()\":{\"notice\":\"How much net total OTokens are allowed to be minted by all strategies\"},\"netOusdMintedForStrategy()\":{\"notice\":\"How much OTokens are currently minted by the strategy\"},\"ousdMetaStrategy()\":{\"notice\":\"Metapool strategy that is allowed to mint/burn OTokens without changing collateral\"},\"priceProvider()\":{\"notice\":\"Address of the Oracle price provider contract\"},\"priceUnitMint(address)\":{\"notice\":\"Returns the total price in 18 digit units for a given asset. Never goes above 1, since that is how we price mints.\"},\"priceUnitRedeem(address)\":{\"notice\":\"Returns the total price in 18 digit unit for a given asset. Never goes below 1, since that is how we price redeems\"},\"rebase()\":{\"notice\":\"Calculate the total value of assets held by the Vault and all strategies and update the supply of OTokens.\"},\"rebasePaused()\":{\"notice\":\"pause rebasing if true\"},\"rebaseThreshold()\":{\"notice\":\"OToken mints over this amount automatically rebase. 18 decimals.\"},\"redeem(uint256,uint256)\":{\"notice\":\"Withdraw a supported asset and burn OTokens.\"},\"redeemAll(uint256)\":{\"notice\":\"Withdraw a supported asset and burn all OTokens.\"},\"redeemFeeBps()\":{\"notice\":\"Redemption fee in basis points. eg 50 = 0.5%\"},\"setAdminImpl(address)\":{\"notice\":\"set the implementation for the admin, this needs to be in a base class else we cannot set it\"},\"strategistAddr()\":{\"notice\":\"Address of the Strategist\"},\"totalValue()\":{\"notice\":\"Determine the total value of assets held by the vault and its strategies.\"},\"transferGovernance(address)\":{\"notice\":\"Transfers Governance of the contract to a new account (`newGovernor`). Can only be called by the current Governor. Must be claimed for this to complete\"},\"trusteeAddress()\":{\"notice\":\"Trustee contract that can collect a percentage of yield\"},\"trusteeFeeBps()\":{\"notice\":\"Amount of yield collected in basis points. eg 2000 = 20%\"},\"vaultBuffer()\":{\"notice\":\"Percentage of assets to keep in Vault to handle (most) withdrawals. 100% = 1e18.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vault/OETHVaultCore.sol\":\"OETHVaultCore\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (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 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 `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, 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 `sender` to `recipient` 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 sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\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\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\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 function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n// CAUTION\\n// This version of SafeMath should only be used with Solidity 0.8 or later,\\n// because it relies on the compiler's built in overflow checks.\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations.\\n *\\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\\n * now has built in overflow checking.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator.\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(\\n uint256 a,\\n uint256 b,\\n string memory errorMessage\\n ) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa2f576be637946f767aa56601c26d717f48a0aff44f82e46f13807eea1009a21\",\"license\":\"MIT\"},\"contracts/governance/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Base for contracts that are managed by the Origin Protocol's Governor.\\n * @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change\\n * from owner to governor and renounce methods removed. Does not use\\n * Context.sol like Ownable.sol does for simplification.\\n * @author Origin Protocol Inc\\n */\\ncontract Governable {\\n // Storage position of the owner and pendingOwner of the contract\\n // keccak256(\\\"OUSD.governor\\\");\\n bytes32 private constant governorPosition =\\n 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\\n\\n // keccak256(\\\"OUSD.pending.governor\\\");\\n bytes32 private constant pendingGovernorPosition =\\n 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\\n\\n // keccak256(\\\"OUSD.reentry.status\\\");\\n bytes32 private constant reentryStatusPosition =\\n 0x53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535;\\n\\n // See OpenZeppelin ReentrancyGuard implementation\\n uint256 constant _NOT_ENTERED = 1;\\n uint256 constant _ENTERED = 2;\\n\\n event PendingGovernorshipTransfer(\\n address indexed previousGovernor,\\n address indexed newGovernor\\n );\\n\\n event GovernorshipTransferred(\\n address indexed previousGovernor,\\n address indexed newGovernor\\n );\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial Governor.\\n */\\n constructor() {\\n _setGovernor(msg.sender);\\n emit GovernorshipTransferred(address(0), _governor());\\n }\\n\\n /**\\n * @notice Returns the address of the current Governor.\\n */\\n function governor() public view returns (address) {\\n return _governor();\\n }\\n\\n /**\\n * @dev Returns the address of the current Governor.\\n */\\n function _governor() internal view returns (address governorOut) {\\n bytes32 position = governorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n governorOut := sload(position)\\n }\\n }\\n\\n /**\\n * @dev Returns the address of the pending Governor.\\n */\\n function _pendingGovernor()\\n internal\\n view\\n returns (address pendingGovernor)\\n {\\n bytes32 position = pendingGovernorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n pendingGovernor := sload(position)\\n }\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the Governor.\\n */\\n modifier onlyGovernor() {\\n require(isGovernor(), \\\"Caller is not the Governor\\\");\\n _;\\n }\\n\\n /**\\n * @notice Returns true if the caller is the current Governor.\\n */\\n function isGovernor() public view returns (bool) {\\n return msg.sender == _governor();\\n }\\n\\n function _setGovernor(address newGovernor) internal {\\n bytes32 position = governorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n bytes32 position = reentryStatusPosition;\\n uint256 _reentry_status;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n _reentry_status := sload(position)\\n }\\n\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_reentry_status != _ENTERED, \\\"Reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, _ENTERED)\\n }\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, _NOT_ENTERED)\\n }\\n }\\n\\n function _setPendingGovernor(address newGovernor) internal {\\n bytes32 position = pendingGovernorPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @notice Transfers Governance of the contract to a new account (`newGovernor`).\\n * Can only be called by the current Governor. Must be claimed for this to complete\\n * @param _newGovernor Address of the new Governor\\n */\\n function transferGovernance(address _newGovernor) external onlyGovernor {\\n _setPendingGovernor(_newGovernor);\\n emit PendingGovernorshipTransfer(_governor(), _newGovernor);\\n }\\n\\n /**\\n * @notice Claim Governance of the contract to a new account (`newGovernor`).\\n * Can only be called by the new Governor.\\n */\\n function claimGovernance() external {\\n require(\\n msg.sender == _pendingGovernor(),\\n \\\"Only the pending Governor can complete the claim\\\"\\n );\\n _changeGovernor(msg.sender);\\n }\\n\\n /**\\n * @dev Change Governance of the contract to a new account (`newGovernor`).\\n * @param _newGovernor Address of the new Governor\\n */\\n function _changeGovernor(address _newGovernor) internal {\\n require(_newGovernor != address(0), \\\"New Governor is address(0)\\\");\\n emit GovernorshipTransferred(_governor(), _newGovernor);\\n _setGovernor(_newGovernor);\\n }\\n}\\n\",\"keccak256\":\"0xb7133d6ce7a9e673ff79fcedb3fd41ae6e58e251f94915bb65731abe524270b4\",\"license\":\"MIT\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xa562062698aa12572123b36dfd2072f1a39e44fed2031cc19c2c9fd522f96ec2\",\"license\":\"MIT\"},\"contracts/interfaces/IGetExchangeRateToken.sol\":{\"content\":\"pragma solidity ^0.8.0;\\n\\ninterface IGetExchangeRateToken {\\n function getExchangeRate() external view returns (uint256 _exchangeRate);\\n}\\n\",\"keccak256\":\"0x641d5892d570f3f9e256d39a9571e58b02c39368726b01c4cdf7d91f45e349d8\"},\"contracts/interfaces/IOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOracle {\\n /**\\n * @dev returns the asset price in USD, in 8 decimal digits.\\n *\\n * The version of priceProvider deployed for OETH has 18 decimal digits\\n */\\n function price(address asset) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x9eabf152389f145c9c23ed71972af73fb1708cbc4b26e524a9ba29a557b7cfe5\",\"license\":\"MIT\"},\"contracts/interfaces/IStrategy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Platform interface to integrate with lending platform like Compound, AAVE etc.\\n */\\ninterface IStrategy {\\n /**\\n * @dev Deposit the given asset to platform\\n * @param _asset asset address\\n * @param _amount Amount to deposit\\n */\\n function deposit(address _asset, uint256 _amount) external;\\n\\n /**\\n * @dev Deposit the entire balance of all supported assets in the Strategy\\n * to the platform\\n */\\n function depositAll() external;\\n\\n /**\\n * @dev Withdraw given asset from Lending platform\\n */\\n function withdraw(\\n address _recipient,\\n address _asset,\\n uint256 _amount\\n ) external;\\n\\n /**\\n * @dev Liquidate all assets in strategy and return them to Vault.\\n */\\n function withdrawAll() external;\\n\\n /**\\n * @dev Returns the current balance of the given asset.\\n */\\n function checkBalance(address _asset)\\n external\\n view\\n returns (uint256 balance);\\n\\n /**\\n * @dev Returns bool indicating whether strategy supports asset.\\n */\\n function supportsAsset(address _asset) external view returns (bool);\\n\\n /**\\n * @dev Collect reward tokens from the Strategy.\\n */\\n function collectRewardTokens() external;\\n\\n /**\\n * @dev The address array of the reward tokens for the Strategy.\\n */\\n function getRewardTokenAddresses() external view returns (address[] memory);\\n}\\n\",\"keccak256\":\"0xb291e409a9b95527f9ed19cd6bff8eeb9921a21c1f5194a48c0bb9ce6613959a\",\"license\":\"MIT\"},\"contracts/token/OUSD.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OUSD Token Contract\\n * @dev ERC20 compatible contract for OUSD\\n * @dev Implements an elastic supply\\n * @author Origin Protocol Inc\\n */\\nimport { SafeMath } from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport { Initializable } from \\\"../utils/Initializable.sol\\\";\\nimport { InitializableERC20Detailed } from \\\"../utils/InitializableERC20Detailed.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\nimport { Governable } from \\\"../governance/Governable.sol\\\";\\n\\n/**\\n * NOTE that this is an ERC20 token but the invariant that the sum of\\n * balanceOf(x) for all x is not >= totalSupply(). This is a consequence of the\\n * rebasing design. Any integrations with OUSD should be aware.\\n */\\n\\ncontract OUSD is Initializable, InitializableERC20Detailed, Governable {\\n using SafeMath for uint256;\\n using StableMath for uint256;\\n\\n event TotalSupplyUpdatedHighres(\\n uint256 totalSupply,\\n uint256 rebasingCredits,\\n uint256 rebasingCreditsPerToken\\n );\\n event AccountRebasingEnabled(address account);\\n event AccountRebasingDisabled(address account);\\n\\n enum RebaseOptions {\\n NotSet,\\n OptOut,\\n OptIn\\n }\\n\\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\\n uint256 public _totalSupply;\\n mapping(address => mapping(address => uint256)) private _allowances;\\n address public vaultAddress = address(0);\\n mapping(address => uint256) private _creditBalances;\\n uint256 private _rebasingCredits;\\n uint256 private _rebasingCreditsPerToken;\\n // Frozen address/credits are non rebasing (value is held in contracts which\\n // do not receive yield unless they explicitly opt in)\\n uint256 public nonRebasingSupply;\\n mapping(address => uint256) public nonRebasingCreditsPerToken;\\n mapping(address => RebaseOptions) public rebaseState;\\n mapping(address => uint256) public isUpgraded;\\n\\n uint256 private constant RESOLUTION_INCREASE = 1e9;\\n\\n function initialize(\\n string calldata _nameArg,\\n string calldata _symbolArg,\\n address _vaultAddress,\\n uint256 _initialCreditsPerToken\\n ) external onlyGovernor initializer {\\n InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);\\n _rebasingCreditsPerToken = _initialCreditsPerToken;\\n vaultAddress = _vaultAddress;\\n }\\n\\n /**\\n * @dev Verifies that the caller is the Vault contract\\n */\\n modifier onlyVault() {\\n require(vaultAddress == msg.sender, \\\"Caller is not the Vault\\\");\\n _;\\n }\\n\\n /**\\n * @return The total supply of OUSD.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @return Low resolution rebasingCreditsPerToken\\n */\\n function rebasingCreditsPerToken() public view returns (uint256) {\\n return _rebasingCreditsPerToken / RESOLUTION_INCREASE;\\n }\\n\\n /**\\n * @return Low resolution total number of rebasing credits\\n */\\n function rebasingCredits() public view returns (uint256) {\\n return _rebasingCredits / RESOLUTION_INCREASE;\\n }\\n\\n /**\\n * @return High resolution rebasingCreditsPerToken\\n */\\n function rebasingCreditsPerTokenHighres() public view returns (uint256) {\\n return _rebasingCreditsPerToken;\\n }\\n\\n /**\\n * @return High resolution total number of rebasing credits\\n */\\n function rebasingCreditsHighres() public view returns (uint256) {\\n return _rebasingCredits;\\n }\\n\\n /**\\n * @dev Gets the balance of the specified address.\\n * @param _account Address to query the balance of.\\n * @return A uint256 representing the amount of base units owned by the\\n * specified address.\\n */\\n function balanceOf(address _account)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n if (_creditBalances[_account] == 0) return 0;\\n return\\n _creditBalances[_account].divPrecisely(_creditsPerToken(_account));\\n }\\n\\n /**\\n * @dev Gets the credits balance of the specified address.\\n * @dev Backwards compatible with old low res credits per token.\\n * @param _account The address to query the balance of.\\n * @return (uint256, uint256) Credit balance and credits per token of the\\n * address\\n */\\n function creditsBalanceOf(address _account)\\n public\\n view\\n returns (uint256, uint256)\\n {\\n uint256 cpt = _creditsPerToken(_account);\\n if (cpt == 1e27) {\\n // For a period before the resolution upgrade, we created all new\\n // contract accounts at high resolution. Since they are not changing\\n // as a result of this upgrade, we will return their true values\\n return (_creditBalances[_account], cpt);\\n } else {\\n return (\\n _creditBalances[_account] / RESOLUTION_INCREASE,\\n cpt / RESOLUTION_INCREASE\\n );\\n }\\n }\\n\\n /**\\n * @dev Gets the credits balance of the specified address.\\n * @param _account The address to query the balance of.\\n * @return (uint256, uint256, bool) Credit balance, credits per token of the\\n * address, and isUpgraded\\n */\\n function creditsBalanceOfHighres(address _account)\\n public\\n view\\n returns (\\n uint256,\\n uint256,\\n bool\\n )\\n {\\n return (\\n _creditBalances[_account],\\n _creditsPerToken(_account),\\n isUpgraded[_account] == 1\\n );\\n }\\n\\n /**\\n * @dev Transfer tokens to a specified address.\\n * @param _to the address to transfer to.\\n * @param _value the amount to be transferred.\\n * @return true on success.\\n */\\n function transfer(address _to, uint256 _value)\\n public\\n override\\n returns (bool)\\n {\\n require(_to != address(0), \\\"Transfer to zero address\\\");\\n require(\\n _value <= balanceOf(msg.sender),\\n \\\"Transfer greater than balance\\\"\\n );\\n\\n _executeTransfer(msg.sender, _to, _value);\\n\\n emit Transfer(msg.sender, _to, _value);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Transfer tokens from one address to another.\\n * @param _from The address you want to send tokens from.\\n * @param _to The address you want to transfer to.\\n * @param _value The amount of tokens to be transferred.\\n */\\n function transferFrom(\\n address _from,\\n address _to,\\n uint256 _value\\n ) public override returns (bool) {\\n require(_to != address(0), \\\"Transfer to zero address\\\");\\n require(_value <= balanceOf(_from), \\\"Transfer greater than balance\\\");\\n\\n _allowances[_from][msg.sender] = _allowances[_from][msg.sender].sub(\\n _value\\n );\\n\\n _executeTransfer(_from, _to, _value);\\n\\n emit Transfer(_from, _to, _value);\\n\\n return true;\\n }\\n\\n /**\\n * @dev Update the count of non rebasing credits in response to a transfer\\n * @param _from The address you want to send tokens from.\\n * @param _to The address you want to transfer to.\\n * @param _value Amount of OUSD to transfer\\n */\\n function _executeTransfer(\\n address _from,\\n address _to,\\n uint256 _value\\n ) internal {\\n bool isNonRebasingTo = _isNonRebasingAccount(_to);\\n bool isNonRebasingFrom = _isNonRebasingAccount(_from);\\n\\n // Credits deducted and credited might be different due to the\\n // differing creditsPerToken used by each account\\n uint256 creditsCredited = _value.mulTruncate(_creditsPerToken(_to));\\n uint256 creditsDeducted = _value.mulTruncate(_creditsPerToken(_from));\\n\\n _creditBalances[_from] = _creditBalances[_from].sub(\\n creditsDeducted,\\n \\\"Transfer amount exceeds balance\\\"\\n );\\n _creditBalances[_to] = _creditBalances[_to].add(creditsCredited);\\n\\n if (isNonRebasingTo && !isNonRebasingFrom) {\\n // Transfer to non-rebasing account from rebasing account, credits\\n // are removed from the non rebasing tally\\n nonRebasingSupply = nonRebasingSupply.add(_value);\\n // Update rebasingCredits by subtracting the deducted amount\\n _rebasingCredits = _rebasingCredits.sub(creditsDeducted);\\n } else if (!isNonRebasingTo && isNonRebasingFrom) {\\n // Transfer to rebasing account from non-rebasing account\\n // Decreasing non-rebasing credits by the amount that was sent\\n nonRebasingSupply = nonRebasingSupply.sub(_value);\\n // Update rebasingCredits by adding the credited amount\\n _rebasingCredits = _rebasingCredits.add(creditsCredited);\\n }\\n }\\n\\n /**\\n * @dev Function to check the amount of tokens that _owner has allowed to\\n * `_spender`.\\n * @param _owner The address which owns the funds.\\n * @param _spender The address which will spend the funds.\\n * @return The number of tokens still available for the _spender.\\n */\\n function allowance(address _owner, address _spender)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n return _allowances[_owner][_spender];\\n }\\n\\n /**\\n * @dev Approve the passed address to spend the specified amount of tokens\\n * on behalf of msg.sender. This method is included for ERC20\\n * compatibility. `increaseAllowance` and `decreaseAllowance` should be\\n * used instead.\\n *\\n * Changing an allowance with this method brings the risk that someone\\n * may transfer both the old and the new allowance - if they are both\\n * greater than zero - if a transfer transaction is mined before the\\n * later approve() call is mined.\\n * @param _spender The address which will spend the funds.\\n * @param _value The amount of tokens to be spent.\\n */\\n function approve(address _spender, uint256 _value)\\n public\\n override\\n returns (bool)\\n {\\n _allowances[msg.sender][_spender] = _value;\\n emit Approval(msg.sender, _spender, _value);\\n return true;\\n }\\n\\n /**\\n * @dev Increase the amount of tokens that an owner has allowed to\\n * `_spender`.\\n * This method should be used instead of approve() to avoid the double\\n * approval vulnerability described above.\\n * @param _spender The address which will spend the funds.\\n * @param _addedValue The amount of tokens to increase the allowance by.\\n */\\n function increaseAllowance(address _spender, uint256 _addedValue)\\n public\\n returns (bool)\\n {\\n _allowances[msg.sender][_spender] = _allowances[msg.sender][_spender]\\n .add(_addedValue);\\n emit Approval(msg.sender, _spender, _allowances[msg.sender][_spender]);\\n return true;\\n }\\n\\n /**\\n * @dev Decrease the amount of tokens that an owner has allowed to\\n `_spender`.\\n * @param _spender The address which will spend the funds.\\n * @param _subtractedValue The amount of tokens to decrease the allowance\\n * by.\\n */\\n function decreaseAllowance(address _spender, uint256 _subtractedValue)\\n public\\n returns (bool)\\n {\\n uint256 oldValue = _allowances[msg.sender][_spender];\\n if (_subtractedValue >= oldValue) {\\n _allowances[msg.sender][_spender] = 0;\\n } else {\\n _allowances[msg.sender][_spender] = oldValue.sub(_subtractedValue);\\n }\\n emit Approval(msg.sender, _spender, _allowances[msg.sender][_spender]);\\n return true;\\n }\\n\\n /**\\n * @dev Mints new tokens, increasing totalSupply.\\n */\\n function mint(address _account, uint256 _amount) external onlyVault {\\n _mint(_account, _amount);\\n }\\n\\n /**\\n * @dev Creates `_amount` tokens and assigns them to `_account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address _account, uint256 _amount) internal nonReentrant {\\n require(_account != address(0), \\\"Mint to the zero address\\\");\\n\\n bool isNonRebasingAccount = _isNonRebasingAccount(_account);\\n\\n uint256 creditAmount = _amount.mulTruncate(_creditsPerToken(_account));\\n _creditBalances[_account] = _creditBalances[_account].add(creditAmount);\\n\\n // If the account is non rebasing and doesn't have a set creditsPerToken\\n // then set it i.e. this is a mint from a fresh contract\\n if (isNonRebasingAccount) {\\n nonRebasingSupply = nonRebasingSupply.add(_amount);\\n } else {\\n _rebasingCredits = _rebasingCredits.add(creditAmount);\\n }\\n\\n _totalSupply = _totalSupply.add(_amount);\\n\\n require(_totalSupply < MAX_SUPPLY, \\\"Max supply\\\");\\n\\n emit Transfer(address(0), _account, _amount);\\n }\\n\\n /**\\n * @dev Burns tokens, decreasing totalSupply.\\n */\\n function burn(address account, uint256 amount) external onlyVault {\\n _burn(account, amount);\\n }\\n\\n /**\\n * @dev Destroys `_amount` tokens from `_account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements\\n *\\n * - `_account` cannot be the zero address.\\n * - `_account` must have at least `_amount` tokens.\\n */\\n function _burn(address _account, uint256 _amount) internal nonReentrant {\\n require(_account != address(0), \\\"Burn from the zero address\\\");\\n if (_amount == 0) {\\n return;\\n }\\n\\n bool isNonRebasingAccount = _isNonRebasingAccount(_account);\\n uint256 creditAmount = _amount.mulTruncate(_creditsPerToken(_account));\\n uint256 currentCredits = _creditBalances[_account];\\n\\n // Remove the credits, burning rounding errors\\n if (\\n currentCredits == creditAmount || currentCredits - 1 == creditAmount\\n ) {\\n // Handle dust from rounding\\n _creditBalances[_account] = 0;\\n } else if (currentCredits > creditAmount) {\\n _creditBalances[_account] = _creditBalances[_account].sub(\\n creditAmount\\n );\\n } else {\\n revert(\\\"Remove exceeds balance\\\");\\n }\\n\\n // Remove from the credit tallies and non-rebasing supply\\n if (isNonRebasingAccount) {\\n nonRebasingSupply = nonRebasingSupply.sub(_amount);\\n } else {\\n _rebasingCredits = _rebasingCredits.sub(creditAmount);\\n }\\n\\n _totalSupply = _totalSupply.sub(_amount);\\n\\n emit Transfer(_account, address(0), _amount);\\n }\\n\\n /**\\n * @dev Get the credits per token for an account. Returns a fixed amount\\n * if the account is non-rebasing.\\n * @param _account Address of the account.\\n */\\n function _creditsPerToken(address _account)\\n internal\\n view\\n returns (uint256)\\n {\\n if (nonRebasingCreditsPerToken[_account] != 0) {\\n return nonRebasingCreditsPerToken[_account];\\n } else {\\n return _rebasingCreditsPerToken;\\n }\\n }\\n\\n /**\\n * @dev Is an account using rebasing accounting or non-rebasing accounting?\\n * Also, ensure contracts are non-rebasing if they have not opted in.\\n * @param _account Address of the account.\\n */\\n function _isNonRebasingAccount(address _account) internal returns (bool) {\\n bool isContract = Address.isContract(_account);\\n if (isContract && rebaseState[_account] == RebaseOptions.NotSet) {\\n _ensureRebasingMigration(_account);\\n }\\n return nonRebasingCreditsPerToken[_account] > 0;\\n }\\n\\n /**\\n * @dev Ensures internal account for rebasing and non-rebasing credits and\\n * supply is updated following deployment of frozen yield change.\\n */\\n function _ensureRebasingMigration(address _account) internal {\\n if (nonRebasingCreditsPerToken[_account] == 0) {\\n emit AccountRebasingDisabled(_account);\\n if (_creditBalances[_account] == 0) {\\n // Since there is no existing balance, we can directly set to\\n // high resolution, and do not have to do any other bookkeeping\\n nonRebasingCreditsPerToken[_account] = 1e27;\\n } else {\\n // Migrate an existing account:\\n\\n // Set fixed credits per token for this account\\n nonRebasingCreditsPerToken[_account] = _rebasingCreditsPerToken;\\n // Update non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.add(balanceOf(_account));\\n // Update credit tallies\\n _rebasingCredits = _rebasingCredits.sub(\\n _creditBalances[_account]\\n );\\n }\\n }\\n }\\n\\n /**\\n * @notice Enable rebasing for an account.\\n * @dev Add a contract address to the non-rebasing exception list. The\\n * address's balance will be part of rebases and the account will be exposed\\n * to upside and downside.\\n * @param _account Address of the account.\\n */\\n function governanceRebaseOptIn(address _account)\\n public\\n nonReentrant\\n onlyGovernor\\n {\\n _rebaseOptIn(_account);\\n }\\n\\n /**\\n * @dev Add a contract address to the non-rebasing exception list. The\\n * address's balance will be part of rebases and the account will be exposed\\n * to upside and downside.\\n */\\n function rebaseOptIn() public nonReentrant {\\n _rebaseOptIn(msg.sender);\\n }\\n\\n function _rebaseOptIn(address _account) internal {\\n require(_isNonRebasingAccount(_account), \\\"Account has not opted out\\\");\\n\\n // Convert balance into the same amount at the current exchange rate\\n uint256 newCreditBalance = _creditBalances[_account]\\n .mul(_rebasingCreditsPerToken)\\n .div(_creditsPerToken(_account));\\n\\n // Decreasing non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.sub(balanceOf(_account));\\n\\n _creditBalances[_account] = newCreditBalance;\\n\\n // Increase rebasing credits, totalSupply remains unchanged so no\\n // adjustment necessary\\n _rebasingCredits = _rebasingCredits.add(_creditBalances[_account]);\\n\\n rebaseState[_account] = RebaseOptions.OptIn;\\n\\n // Delete any fixed credits per token\\n delete nonRebasingCreditsPerToken[_account];\\n emit AccountRebasingEnabled(_account);\\n }\\n\\n /**\\n * @dev Explicitly mark that an address is non-rebasing.\\n */\\n function rebaseOptOut() public nonReentrant {\\n require(!_isNonRebasingAccount(msg.sender), \\\"Account has not opted in\\\");\\n\\n // Increase non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.add(balanceOf(msg.sender));\\n // Set fixed credits per token\\n nonRebasingCreditsPerToken[msg.sender] = _rebasingCreditsPerToken;\\n\\n // Decrease rebasing credits, total supply remains unchanged so no\\n // adjustment necessary\\n _rebasingCredits = _rebasingCredits.sub(_creditBalances[msg.sender]);\\n\\n // Mark explicitly opted out of rebasing\\n rebaseState[msg.sender] = RebaseOptions.OptOut;\\n emit AccountRebasingDisabled(msg.sender);\\n }\\n\\n /**\\n * @dev Modify the supply without minting new tokens. This uses a change in\\n * the exchange rate between \\\"credits\\\" and OUSD tokens to change balances.\\n * @param _newTotalSupply New total supply of OUSD.\\n */\\n function changeSupply(uint256 _newTotalSupply)\\n external\\n onlyVault\\n nonReentrant\\n {\\n require(_totalSupply > 0, \\\"Cannot increase 0 supply\\\");\\n\\n if (_totalSupply == _newTotalSupply) {\\n emit TotalSupplyUpdatedHighres(\\n _totalSupply,\\n _rebasingCredits,\\n _rebasingCreditsPerToken\\n );\\n return;\\n }\\n\\n _totalSupply = _newTotalSupply > MAX_SUPPLY\\n ? MAX_SUPPLY\\n : _newTotalSupply;\\n\\n _rebasingCreditsPerToken = _rebasingCredits.divPrecisely(\\n _totalSupply.sub(nonRebasingSupply)\\n );\\n\\n require(_rebasingCreditsPerToken > 0, \\\"Invalid change in supply\\\");\\n\\n _totalSupply = _rebasingCredits\\n .divPrecisely(_rebasingCreditsPerToken)\\n .add(nonRebasingSupply);\\n\\n emit TotalSupplyUpdatedHighres(\\n _totalSupply,\\n _rebasingCredits,\\n _rebasingCreditsPerToken\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2dc66b1ba02716d64eb47dd9117fda62650d8b57669e6c351437e0ad29ad5f19\",\"license\":\"MIT\"},\"contracts/utils/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { IBasicToken } from \\\"../interfaces/IBasicToken.sol\\\";\\n\\nlibrary Helpers {\\n /**\\n * @notice Fetch the `symbol()` from an ERC20 token\\n * @dev Grabs the `symbol()` from a contract\\n * @param _token Address of the ERC20 token\\n * @return string Symbol of the ERC20 token\\n */\\n function getSymbol(address _token) internal view returns (string memory) {\\n string memory symbol = IBasicToken(_token).symbol();\\n return symbol;\\n }\\n\\n /**\\n * @notice Fetch the `decimals()` from an ERC20 token\\n * @dev Grabs the `decimals()` from a contract and fails if\\n * the decimal value does not live within a certain range\\n * @param _token Address of the ERC20 token\\n * @return uint256 Decimals of the ERC20 token\\n */\\n function getDecimals(address _token) internal view returns (uint256) {\\n uint256 decimals = IBasicToken(_token).decimals();\\n require(\\n decimals >= 4 && decimals <= 18,\\n \\\"Token must have sufficient decimal places\\\"\\n );\\n\\n return decimals;\\n }\\n}\\n\",\"keccak256\":\"0x108b7a69e0140da0072ca18f90a03a3340574400f81aa6076cd2cccdf13699c2\",\"license\":\"MIT\"},\"contracts/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Base contract any contracts that need to initialize state after deployment.\\n * @author Origin Protocol Inc\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n require(\\n initializing || !initialized,\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n\\n bool isTopLevelCall = !initializing;\\n if (isTopLevelCall) {\\n initializing = true;\\n initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n initializing = false;\\n }\\n }\\n\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0xaadbcc138114afed4af4f353c2ced2916e6ee14be91434789187f192caf0d786\",\"license\":\"MIT\"},\"contracts/utils/InitializableERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @dev Optional functions from the ERC20 standard.\\n * Converted from openzeppelin/contracts/token/ERC20/ERC20Detailed.sol\\n * @author Origin Protocol Inc\\n */\\nabstract contract InitializableERC20Detailed is IERC20 {\\n // Storage gap to skip storage from prior to OUSD reset\\n uint256[100] private _____gap;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of\\n * these values are immutable: they can only be set once during\\n * construction.\\n * @notice To avoid variable shadowing appended `Arg` after arguments name.\\n */\\n function _initialize(\\n string memory nameArg,\\n string memory symbolArg,\\n uint8 decimalsArg\\n ) internal {\\n _name = nameArg;\\n _symbol = symbolArg;\\n _decimals = decimalsArg;\\n }\\n\\n /**\\n * @notice Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @notice Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @notice Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n}\\n\",\"keccak256\":\"0xe35ac2d813a30d845a3b52bba72588d7e936c2b3f3373d15568c14db46aeed60\",\"license\":\"MIT\"},\"contracts/utils/StableMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\n\\n// Based on StableMath from Stability Labs Pty. Ltd.\\n// https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol\\n\\nlibrary StableMath {\\n using SafeMath for uint256;\\n\\n /**\\n * @dev Scaling unit for use in specific calculations,\\n * where 1 * 10**18, or 1e18 represents a unit '1'\\n */\\n uint256 private constant FULL_SCALE = 1e18;\\n\\n /***************************************\\n Helpers\\n ****************************************/\\n\\n /**\\n * @dev Adjust the scale of an integer\\n * @param to Decimals to scale to\\n * @param from Decimals to scale from\\n */\\n function scaleBy(\\n uint256 x,\\n uint256 to,\\n uint256 from\\n ) internal pure returns (uint256) {\\n if (to > from) {\\n x = x.mul(10**(to - from));\\n } else if (to < from) {\\n // slither-disable-next-line divide-before-multiply\\n x = x.div(10**(from - to));\\n }\\n return x;\\n }\\n\\n /***************************************\\n Precise Arithmetic\\n ****************************************/\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the full scale\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit\\n */\\n function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) {\\n return mulTruncateScale(x, y, FULL_SCALE);\\n }\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the given scale. For example,\\n * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @param scale Scale unit\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit\\n */\\n function mulTruncateScale(\\n uint256 x,\\n uint256 y,\\n uint256 scale\\n ) internal pure returns (uint256) {\\n // e.g. assume scale = fullScale\\n // z = 10e18 * 9e17 = 9e36\\n uint256 z = x.mul(y);\\n // return 9e36 / 1e18 = 9e18\\n return z.div(scale);\\n }\\n\\n /**\\n * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result\\n * @param x Left hand input to multiplication\\n * @param y Right hand input to multiplication\\n * @return Result after multiplying the two inputs and then dividing by the shared\\n * scale unit, rounded up to the closest base unit.\\n */\\n function mulTruncateCeil(uint256 x, uint256 y)\\n internal\\n pure\\n returns (uint256)\\n {\\n // e.g. 8e17 * 17268172638 = 138145381104e17\\n uint256 scaled = x.mul(y);\\n // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17\\n uint256 ceil = scaled.add(FULL_SCALE.sub(1));\\n // e.g. 13814538111.399...e18 / 1e18 = 13814538111\\n return ceil.div(FULL_SCALE);\\n }\\n\\n /**\\n * @dev Precisely divides two units, by first scaling the left hand operand. Useful\\n * for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)\\n * @param x Left hand input to division\\n * @param y Right hand input to division\\n * @return Result after multiplying the left operand by the scale, and\\n * executing the division on the right hand input.\\n */\\n function divPrecisely(uint256 x, uint256 y)\\n internal\\n pure\\n returns (uint256)\\n {\\n // e.g. 8e18 * 1e18 = 8e36\\n uint256 z = x.mul(FULL_SCALE);\\n // e.g. 8e36 / 10e18 = 8e17\\n return z.div(y);\\n }\\n}\\n\",\"keccak256\":\"0x1eb49f6f79045d9e0a8e1dced8e01d9e559e5fac554dcbb53e43140b601b04e7\",\"license\":\"MIT\"},\"contracts/vault/OETHVaultCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\nimport { VaultCore } from \\\"./VaultCore.sol\\\";\\n\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport { IStrategy } from \\\"../interfaces/IStrategy.sol\\\";\\n\\n/**\\n * @title OETH VaultCore Contract\\n * @author Origin Protocol Inc\\n */\\ncontract OETHVaultCore is VaultCore {\\n using SafeERC20 for IERC20;\\n using StableMath for uint256;\\n\\n address public immutable weth;\\n uint256 public wethAssetIndex;\\n\\n constructor(address _weth) {\\n weth = _weth;\\n }\\n\\n /**\\n * @dev Caches WETH's index in `allAssets` variable.\\n * Reduces gas usage by redeem by caching that.\\n */\\n function cacheWETHAssetIndex() external onlyGovernor {\\n uint256 assetCount = allAssets.length;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n if (allAssets[i] == weth) {\\n wethAssetIndex = i;\\n break;\\n }\\n }\\n\\n require(allAssets[wethAssetIndex] == weth, \\\"Invalid WETH Asset Index\\\");\\n }\\n\\n // @inheritdoc VaultCore\\n function _mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) internal virtual override {\\n require(_asset == weth, \\\"Unsupported asset for minting\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n require(\\n _amount >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n\\n emit Mint(msg.sender, _amount);\\n\\n // Rebase must happen before any transfers occur.\\n if (!rebasePaused && _amount >= rebaseThreshold) {\\n _rebase();\\n }\\n\\n // Mint oTokens\\n oUSD.mint(msg.sender, _amount);\\n\\n // Transfer the deposited coins to the vault\\n IERC20(_asset).safeTransferFrom(msg.sender, address(this), _amount);\\n\\n // Auto-allocate if necessary\\n if (_amount >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n // @inheritdoc VaultCore\\n function _calculateRedeemOutputs(uint256 _amount)\\n internal\\n view\\n virtual\\n override\\n returns (uint256[] memory outputs)\\n {\\n // Overrides `VaultCore._calculateRedeemOutputs` to redeem with only\\n // WETH instead of LST-mix. Doesn't change the function signature\\n // for backward compatibility\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mulTruncateScale(redeemFeeBps, 1e4);\\n _amount = _amount - redeemFee;\\n }\\n\\n // Ensure that the WETH index is cached\\n uint256 _wethAssetIndex = wethAssetIndex;\\n require(\\n allAssets[_wethAssetIndex] == weth,\\n \\\"WETH Asset index not cached\\\"\\n );\\n\\n outputs = new uint256[](allAssets.length);\\n outputs[_wethAssetIndex] = _amount;\\n }\\n\\n // @inheritdoc VaultCore\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n internal\\n virtual\\n override\\n {\\n // Override `VaultCore._redeem` to simplify it. Gets rid of oracle\\n // usage and looping through all assets for LST-mix redeem. Instead\\n // does a simple WETH-only redeem.\\n emit Redeem(msg.sender, _amount);\\n\\n if (_amount == 0) {\\n return;\\n }\\n\\n // Amount excluding fees\\n uint256 amountMinusFee = _calculateRedeemOutputs(_amount)[\\n wethAssetIndex\\n ];\\n\\n require(\\n amountMinusFee >= _minimumUnitAmount,\\n \\\"Redeem amount lower than minimum\\\"\\n );\\n\\n if (IERC20(weth).balanceOf(address(this)) >= amountMinusFee) {\\n // Use Vault funds first if sufficient\\n IERC20(weth).safeTransfer(msg.sender, amountMinusFee);\\n } else {\\n address strategyAddr = assetDefaultStrategies[weth];\\n if (strategyAddr != address(0)) {\\n // Nothing in Vault, but something in Strategy, send from there\\n IStrategy strategy = IStrategy(strategyAddr);\\n strategy.withdraw(msg.sender, weth, amountMinusFee);\\n } else {\\n // Cant find funds anywhere\\n revert(\\\"Liquidity error\\\");\\n }\\n }\\n\\n // Burn OETH from user (including fees)\\n oUSD.burn(msg.sender, _amount);\\n\\n _postRedeem(_amount);\\n }\\n}\\n\",\"keccak256\":\"0x8ae6aada28f768745991b7e6610e325e1331da8fd7e9de045d03f1bc12d65f1e\",\"license\":\"MIT\"},\"contracts/vault/VaultCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OToken VaultCore contract\\n * @notice The Vault contract stores assets. On a deposit, OTokens will be minted\\n and sent to the depositor. On a withdrawal, OTokens will be burned and\\n assets will be sent to the withdrawer. The Vault accepts deposits of\\n interest from yield bearing strategies which will modify the supply\\n of OTokens.\\n * @author Origin Protocol Inc\\n */\\n\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\nimport { IOracle } from \\\"../interfaces/IOracle.sol\\\";\\nimport { IGetExchangeRateToken } from \\\"../interfaces/IGetExchangeRateToken.sol\\\";\\n\\nimport \\\"./VaultInitializer.sol\\\";\\n\\ncontract VaultCore is VaultInitializer {\\n using SafeERC20 for IERC20;\\n using StableMath for uint256;\\n // max signed int\\n uint256 internal constant MAX_INT = 2**255 - 1;\\n // max un-signed int\\n uint256 internal constant MAX_UINT =\\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n\\n /**\\n * @dev Verifies that the rebasing is not paused.\\n */\\n modifier whenNotRebasePaused() {\\n require(!rebasePaused, \\\"Rebasing paused\\\");\\n _;\\n }\\n\\n /**\\n * @dev Verifies that the deposits are not paused.\\n */\\n modifier whenNotCapitalPaused() {\\n require(!capitalPaused, \\\"Capital paused\\\");\\n _;\\n }\\n\\n modifier onlyOusdMetaStrategy() {\\n require(\\n msg.sender == ousdMetaStrategy,\\n \\\"Caller is not the OUSD meta strategy\\\"\\n );\\n _;\\n }\\n\\n /**\\n * @notice Deposit a supported asset and mint OTokens.\\n * @param _asset Address of the asset being deposited\\n * @param _amount Amount of the asset being deposited\\n * @param _minimumOusdAmount Minimum OTokens to mint\\n */\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n _mint(_asset, _amount, _minimumOusdAmount);\\n }\\n\\n function _mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) internal virtual {\\n require(assets[_asset].isSupported, \\\"Asset is not supported\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 units = _toUnits(_amount, _asset);\\n uint256 unitPrice = _toUnitPrice(_asset, true);\\n uint256 priceAdjustedDeposit = (units * unitPrice) / 1e18;\\n\\n if (_minimumOusdAmount > 0) {\\n require(\\n priceAdjustedDeposit >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n }\\n\\n emit Mint(msg.sender, priceAdjustedDeposit);\\n\\n // Rebase must happen before any transfers occur.\\n if (priceAdjustedDeposit >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n // Mint matching amount of OTokens\\n oUSD.mint(msg.sender, priceAdjustedDeposit);\\n\\n // Transfer the deposited coins to the vault\\n IERC20 asset = IERC20(_asset);\\n asset.safeTransferFrom(msg.sender, address(this), _amount);\\n\\n if (priceAdjustedDeposit >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @notice Mint OTokens for a Metapool Strategy\\n * @param _amount Amount of the asset being deposited\\n *\\n * Notice: can't use `nonReentrant` modifier since the `mint` function can\\n * call `allocate`, and that can trigger `ConvexOUSDMetaStrategy` to call this function\\n * while the execution of the `mint` has not yet completed -> causing a `nonReentrant` collision.\\n *\\n * Also important to understand is that this is a limitation imposed by the test suite.\\n * Production / mainnet contracts should never be configured in a way where mint/redeem functions\\n * that are moving funds between the Vault and end user wallets can influence strategies\\n * utilizing this function.\\n */\\n function mintForStrategy(uint256 _amount)\\n external\\n whenNotCapitalPaused\\n onlyOusdMetaStrategy\\n {\\n require(_amount < MAX_INT, \\\"Amount too high\\\");\\n\\n emit Mint(msg.sender, _amount);\\n\\n // safe to cast because of the require check at the beginning of the function\\n netOusdMintedForStrategy += int256(_amount);\\n\\n require(\\n abs(netOusdMintedForStrategy) < netOusdMintForStrategyThreshold,\\n \\\"Minted ousd surpassed netOusdMintForStrategyThreshold.\\\"\\n );\\n\\n // Mint matching amount of OTokens\\n oUSD.mint(msg.sender, _amount);\\n }\\n\\n // In memoriam\\n\\n /**\\n * @notice Withdraw a supported asset and burn OTokens.\\n * @param _amount Amount of OTokens to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n _redeem(_amount, _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn OTokens.\\n * @param _amount Amount of OTokens to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n internal\\n virtual\\n {\\n // Calculate redemption outputs\\n uint256[] memory outputs = _calculateRedeemOutputs(_amount);\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // Send outputs\\n uint256 assetCount = allAssets.length;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n if (outputs[i] == 0) continue;\\n\\n address assetAddr = allAssets[i];\\n\\n if (IERC20(assetAddr).balanceOf(address(this)) >= outputs[i]) {\\n // Use Vault funds first if sufficient\\n IERC20(assetAddr).safeTransfer(msg.sender, outputs[i]);\\n } else {\\n address strategyAddr = assetDefaultStrategies[assetAddr];\\n if (strategyAddr != address(0)) {\\n // Nothing in Vault, but something in Strategy, send from there\\n IStrategy strategy = IStrategy(strategyAddr);\\n strategy.withdraw(msg.sender, assetAddr, outputs[i]);\\n } else {\\n // Cant find funds anywhere\\n revert(\\\"Liquidity error\\\");\\n }\\n }\\n }\\n\\n if (_minimumUnitAmount > 0) {\\n uint256 unitTotal = 0;\\n for (uint256 i = 0; i < outputs.length; ++i) {\\n unitTotal += _toUnits(outputs[i], allAssets[i]);\\n }\\n require(\\n unitTotal >= _minimumUnitAmount,\\n \\\"Redeem amount lower than minimum\\\"\\n );\\n }\\n\\n oUSD.burn(msg.sender, _amount);\\n\\n _postRedeem(_amount);\\n }\\n\\n function _postRedeem(uint256 _amount) internal {\\n // Until we can prove that we won't affect the prices of our assets\\n // by withdrawing them, this should be here.\\n // It's possible that a strategy was off on its asset total, perhaps\\n // a reward token sold for more or for less than anticipated.\\n uint256 totalUnits = 0;\\n if (_amount >= rebaseThreshold && !rebasePaused) {\\n totalUnits = _rebase();\\n } else {\\n totalUnits = _totalValue();\\n }\\n\\n // Check that the OTokens are backed by enough assets\\n if (maxSupplyDiff > 0) {\\n // Allow a max difference of maxSupplyDiff% between\\n // backing assets value and OUSD total supply\\n uint256 diff = oUSD.totalSupply().divPrecisely(totalUnits);\\n require(\\n (diff > 1e18 ? diff - 1e18 : 1e18 - diff) <= maxSupplyDiff,\\n \\\"Backing supply liquidity error\\\"\\n );\\n }\\n }\\n\\n /**\\n * @notice Burn OTokens for Metapool Strategy\\n * @param _amount Amount of OUSD to burn\\n *\\n * @dev Notice: can't use `nonReentrant` modifier since the `redeem` function could\\n * require withdrawal on `ConvexOUSDMetaStrategy` and that one can call `burnForStrategy`\\n * while the execution of the `redeem` has not yet completed -> causing a `nonReentrant` collision.\\n *\\n * Also important to understand is that this is a limitation imposed by the test suite.\\n * Production / mainnet contracts should never be configured in a way where mint/redeem functions\\n * that are moving funds between the Vault and end user wallets can influence strategies\\n * utilizing this function.\\n */\\n function burnForStrategy(uint256 _amount)\\n external\\n whenNotCapitalPaused\\n onlyOusdMetaStrategy\\n {\\n require(_amount < MAX_INT, \\\"Amount too high\\\");\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // safe to cast because of the require check at the beginning of the function\\n netOusdMintedForStrategy -= int256(_amount);\\n\\n require(\\n abs(netOusdMintedForStrategy) < netOusdMintForStrategyThreshold,\\n \\\"Attempting to burn too much OUSD.\\\"\\n );\\n\\n // Burn OTokens\\n oUSD.burn(msg.sender, _amount);\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn all OTokens.\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeemAll(uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n _redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\n **/\\n function allocate() external whenNotCapitalPaused nonReentrant {\\n _allocate();\\n }\\n\\n /**\\n * @dev Allocate unallocated funds on Vault to strategies.\\n **/\\n function _allocate() internal {\\n uint256 vaultValue = _totalValueInVault();\\n // Nothing in vault to allocate\\n if (vaultValue == 0) return;\\n uint256 strategiesValue = _totalValueInStrategies();\\n // We have a method that does the same as this, gas optimisation\\n uint256 calculatedTotalValue = vaultValue + strategiesValue;\\n\\n // We want to maintain a buffer on the Vault so calculate a percentage\\n // modifier to multiply each amount being allocated by to enforce the\\n // vault buffer\\n uint256 vaultBufferModifier;\\n if (strategiesValue == 0) {\\n // Nothing in Strategies, allocate 100% minus the vault buffer to\\n // strategies\\n vaultBufferModifier = uint256(1e18) - vaultBuffer;\\n } else {\\n vaultBufferModifier =\\n (vaultBuffer * calculatedTotalValue) /\\n vaultValue;\\n if (1e18 > vaultBufferModifier) {\\n // E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17\\n // (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault\\n vaultBufferModifier = uint256(1e18) - vaultBufferModifier;\\n } else {\\n // We need to let the buffer fill\\n return;\\n }\\n }\\n if (vaultBufferModifier == 0) return;\\n\\n // Iterate over all assets in the Vault and allocate to the appropriate\\n // strategy\\n uint256 assetCount = allAssets.length;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n IERC20 asset = IERC20(allAssets[i]);\\n uint256 assetBalance = asset.balanceOf(address(this));\\n // No balance, nothing to do here\\n if (assetBalance == 0) continue;\\n\\n // Multiply the balance by the vault buffer modifier and truncate\\n // to the scale of the asset decimals\\n uint256 allocateAmount = assetBalance.mulTruncate(\\n vaultBufferModifier\\n );\\n\\n address depositStrategyAddr = assetDefaultStrategies[\\n address(asset)\\n ];\\n\\n if (depositStrategyAddr != address(0) && allocateAmount > 0) {\\n IStrategy strategy = IStrategy(depositStrategyAddr);\\n // Transfer asset to Strategy and call deposit method to\\n // mint or take required action\\n asset.safeTransfer(address(strategy), allocateAmount);\\n strategy.deposit(address(asset), allocateAmount);\\n emit AssetAllocated(\\n address(asset),\\n depositStrategyAddr,\\n allocateAmount\\n );\\n }\\n }\\n }\\n\\n /**\\n * @notice Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OTokens.\\n */\\n function rebase() external virtual nonReentrant {\\n _rebase();\\n }\\n\\n /**\\n * @dev Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OTokens, optionally sending a\\n * portion of the yield to the trustee.\\n * @return totalUnits Total balance of Vault in units\\n */\\n function _rebase() internal whenNotRebasePaused returns (uint256) {\\n uint256 ousdSupply = oUSD.totalSupply();\\n uint256 vaultValue = _totalValue();\\n if (ousdSupply == 0) {\\n return vaultValue;\\n }\\n\\n // Yield fee collection\\n address _trusteeAddress = trusteeAddress; // gas savings\\n if (_trusteeAddress != address(0) && (vaultValue > ousdSupply)) {\\n uint256 yield = vaultValue - ousdSupply;\\n uint256 fee = yield.mulTruncateScale(trusteeFeeBps, 1e4);\\n require(yield > fee, \\\"Fee must not be greater than yield\\\");\\n if (fee > 0) {\\n oUSD.mint(_trusteeAddress, fee);\\n }\\n emit YieldDistribution(_trusteeAddress, yield, fee);\\n }\\n\\n // Only rachet OToken supply upwards\\n ousdSupply = oUSD.totalSupply(); // Final check should use latest value\\n if (vaultValue > ousdSupply) {\\n oUSD.changeSupply(vaultValue);\\n }\\n return vaultValue;\\n }\\n\\n /**\\n * @notice Determine the total value of assets held by the vault and its\\n * strategies.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function totalValue() external view virtual returns (uint256 value) {\\n value = _totalValue();\\n }\\n\\n /**\\n * @dev Internal Calculate the total value of the assets held by the\\n * vault and its strategies.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValue() internal view virtual returns (uint256 value) {\\n return _totalValueInVault() + _totalValueInStrategies();\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Vault.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValueInVault() internal view returns (uint256 value) {\\n uint256 assetCount = allAssets.length;\\n for (uint256 y = 0; y < assetCount; ++y) {\\n address assetAddr = allAssets[y];\\n uint256 balance = IERC20(assetAddr).balanceOf(address(this));\\n if (balance > 0) {\\n value += _toUnits(balance, assetAddr);\\n }\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Strategies.\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValueInStrategies() internal view returns (uint256 value) {\\n uint256 stratCount = allStrategies.length;\\n for (uint256 i = 0; i < stratCount; ++i) {\\n value = value + _totalValueInStrategy(allStrategies[i]);\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held by strategy.\\n * @param _strategyAddr Address of the strategy\\n * @return value Total value in USD/ETH (1e18)\\n */\\n function _totalValueInStrategy(address _strategyAddr)\\n internal\\n view\\n returns (uint256 value)\\n {\\n IStrategy strategy = IStrategy(_strategyAddr);\\n uint256 assetCount = allAssets.length;\\n for (uint256 y = 0; y < assetCount; ++y) {\\n address assetAddr = allAssets[y];\\n if (strategy.supportsAsset(assetAddr)) {\\n uint256 balance = strategy.checkBalance(assetAddr);\\n if (balance > 0) {\\n value += _toUnits(balance, assetAddr);\\n }\\n }\\n }\\n }\\n\\n /**\\n * @notice Get the balance of an asset held in Vault and all strategies.\\n * @param _asset Address of asset\\n * @return uint256 Balance of asset in decimals of asset\\n */\\n function checkBalance(address _asset) external view returns (uint256) {\\n return _checkBalance(_asset);\\n }\\n\\n /**\\n * @notice Get the balance of an asset held in Vault and all strategies.\\n * @param _asset Address of asset\\n * @return balance Balance of asset in decimals of asset\\n */\\n function _checkBalance(address _asset)\\n internal\\n view\\n virtual\\n returns (uint256 balance)\\n {\\n IERC20 asset = IERC20(_asset);\\n balance = asset.balanceOf(address(this));\\n uint256 stratCount = allStrategies.length;\\n for (uint256 i = 0; i < stratCount; ++i) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n if (strategy.supportsAsset(_asset)) {\\n balance = balance + strategy.checkBalance(_asset);\\n }\\n }\\n }\\n\\n /**\\n * @notice Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned\\n */\\n function calculateRedeemOutputs(uint256 _amount)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n return _calculateRedeemOutputs(_amount);\\n }\\n\\n /**\\n * @dev Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned.\\n * @return outputs Array of amounts respective to the supported assets\\n */\\n function _calculateRedeemOutputs(uint256 _amount)\\n internal\\n view\\n virtual\\n returns (uint256[] memory outputs)\\n {\\n // We always give out coins in proportion to how many we have,\\n // Now if all coins were the same value, this math would easy,\\n // just take the percentage of each coin, and multiply by the\\n // value to be given out. But if coins are worth more than $1,\\n // then we would end up handing out too many coins. We need to\\n // adjust by the total value of coins.\\n //\\n // To do this, we total up the value of our coins, by their\\n // percentages. Then divide what we would otherwise give out by\\n // this number.\\n //\\n // Let say we have 100 DAI at $1.06 and 200 USDT at $1.00.\\n // So for every 1 DAI we give out, we'll be handing out 2 USDT\\n // Our total output ratio is: 33% * 1.06 + 66% * 1.00 = 1.02\\n //\\n // So when calculating the output, we take the percentage of\\n // each coin, times the desired output value, divided by the\\n // totalOutputRatio.\\n //\\n // For example, withdrawing: 30 OUSD:\\n // DAI 33% * 30 / 1.02 = 9.80 DAI\\n // USDT = 66 % * 30 / 1.02 = 19.60 USDT\\n //\\n // Checking these numbers:\\n // 9.80 DAI * 1.06 = $10.40\\n // 19.60 USDT * 1.00 = $19.60\\n //\\n // And so the user gets $10.40 + $19.60 = $30 worth of value.\\n\\n uint256 assetCount = allAssets.length;\\n uint256[] memory assetUnits = new uint256[](assetCount);\\n uint256[] memory assetBalances = new uint256[](assetCount);\\n outputs = new uint256[](assetCount);\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mulTruncateScale(redeemFeeBps, 1e4);\\n _amount = _amount - redeemFee;\\n }\\n\\n // Calculate assets balances and decimals once,\\n // for a large gas savings.\\n uint256 totalUnits = 0;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n address assetAddr = allAssets[i];\\n uint256 balance = _checkBalance(assetAddr);\\n assetBalances[i] = balance;\\n assetUnits[i] = _toUnits(balance, assetAddr);\\n totalUnits = totalUnits + assetUnits[i];\\n }\\n // Calculate totalOutputRatio\\n uint256 totalOutputRatio = 0;\\n for (uint256 i = 0; i < assetCount; ++i) {\\n uint256 unitPrice = _toUnitPrice(allAssets[i], false);\\n uint256 ratio = (assetUnits[i] * unitPrice) / totalUnits;\\n totalOutputRatio = totalOutputRatio + ratio;\\n }\\n // Calculate final outputs\\n uint256 factor = _amount.divPrecisely(totalOutputRatio);\\n for (uint256 i = 0; i < assetCount; ++i) {\\n outputs[i] = (assetBalances[i] * factor) / totalUnits;\\n }\\n }\\n\\n /***************************************\\n Pricing\\n ****************************************/\\n\\n /**\\n * @notice Returns the total price in 18 digit units for a given asset.\\n * Never goes above 1, since that is how we price mints.\\n * @param asset address of the asset\\n * @return price uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\\n */\\n function priceUnitMint(address asset)\\n external\\n view\\n returns (uint256 price)\\n {\\n /* need to supply 1 asset unit in asset's decimals and can not just hard-code\\n * to 1e18 and ignore calling `_toUnits` since we need to consider assets\\n * with the exchange rate\\n */\\n uint256 units = _toUnits(\\n uint256(1e18).scaleBy(_getDecimals(asset), 18),\\n asset\\n );\\n price = (_toUnitPrice(asset, true) * units) / 1e18;\\n }\\n\\n /**\\n * @notice Returns the total price in 18 digit unit for a given asset.\\n * Never goes below 1, since that is how we price redeems\\n * @param asset Address of the asset\\n * @return price uint256: unit (USD / ETH) price for 1 unit of the asset, in 18 decimal fixed\\n */\\n function priceUnitRedeem(address asset)\\n external\\n view\\n returns (uint256 price)\\n {\\n /* need to supply 1 asset unit in asset's decimals and can not just hard-code\\n * to 1e18 and ignore calling `_toUnits` since we need to consider assets\\n * with the exchange rate\\n */\\n uint256 units = _toUnits(\\n uint256(1e18).scaleBy(_getDecimals(asset), 18),\\n asset\\n );\\n price = (_toUnitPrice(asset, false) * units) / 1e18;\\n }\\n\\n /***************************************\\n Utils\\n ****************************************/\\n\\n /**\\n * @dev Convert a quantity of a token into 1e18 fixed decimal \\\"units\\\"\\n * in the underlying base (USD/ETH) used by the vault.\\n * Price is not taken into account, only quantity.\\n *\\n * Examples of this conversion:\\n *\\n * - 1e18 DAI becomes 1e18 units (same decimals)\\n * - 1e6 USDC becomes 1e18 units (decimal conversion)\\n * - 1e18 rETH becomes 1.2e18 units (exchange rate conversion)\\n *\\n * @param _raw Quantity of asset\\n * @param _asset Core Asset address\\n * @return value 1e18 normalized quantity of units\\n */\\n function _toUnits(uint256 _raw, address _asset)\\n internal\\n view\\n returns (uint256)\\n {\\n UnitConversion conversion = assets[_asset].unitConversion;\\n if (conversion == UnitConversion.DECIMALS) {\\n return _raw.scaleBy(18, _getDecimals(_asset));\\n } else if (conversion == UnitConversion.GETEXCHANGERATE) {\\n uint256 exchangeRate = IGetExchangeRateToken(_asset)\\n .getExchangeRate();\\n return (_raw * exchangeRate) / 1e18;\\n } else {\\n revert(\\\"Unsupported conversion type\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns asset's unit price accounting for different asset types\\n * and takes into account the context in which that price exists -\\n * - mint or redeem.\\n *\\n * Note: since we are returning the price of the unit and not the one of the\\n * asset (see comment above how 1 rETH exchanges for 1.2 units) we need\\n * to make the Oracle price adjustment as well since we are pricing the\\n * units and not the assets.\\n *\\n * The price also snaps to a \\\"full unit price\\\" in case a mint or redeem\\n * action would be unfavourable to the protocol.\\n *\\n */\\n function _toUnitPrice(address _asset, bool isMint)\\n internal\\n view\\n returns (uint256 price)\\n {\\n UnitConversion conversion = assets[_asset].unitConversion;\\n price = IOracle(priceProvider).price(_asset);\\n\\n if (conversion == UnitConversion.GETEXCHANGERATE) {\\n uint256 exchangeRate = IGetExchangeRateToken(_asset)\\n .getExchangeRate();\\n price = (price * 1e18) / exchangeRate;\\n } else if (conversion != UnitConversion.DECIMALS) {\\n revert(\\\"Unsupported conversion type\\\");\\n }\\n\\n /* At this stage the price is already adjusted to the unit\\n * so the price checks are agnostic to underlying asset being\\n * pegged to a USD or to an ETH or having a custom exchange rate.\\n */\\n require(price <= MAX_UNIT_PRICE_DRIFT, \\\"Vault: Price exceeds max\\\");\\n require(price >= MIN_UNIT_PRICE_DRIFT, \\\"Vault: Price under min\\\");\\n\\n if (isMint) {\\n /* Never price a normalized unit price for more than one\\n * unit of OETH/OUSD when minting.\\n */\\n if (price > 1e18) {\\n price = 1e18;\\n }\\n require(price >= MINT_MINIMUM_UNIT_PRICE, \\\"Asset price below peg\\\");\\n } else {\\n /* Never give out more than 1 normalized unit amount of assets\\n * for one unit of OETH/OUSD when redeeming.\\n */\\n if (price < 1e18) {\\n price = 1e18;\\n }\\n }\\n }\\n\\n function _getDecimals(address _asset)\\n internal\\n view\\n returns (uint256 decimals)\\n {\\n decimals = assets[_asset].decimals;\\n require(decimals > 0, \\\"Decimals not cached\\\");\\n }\\n\\n /**\\n * @notice Return the number of assets supported by the Vault.\\n */\\n function getAssetCount() public view returns (uint256) {\\n return allAssets.length;\\n }\\n\\n /**\\n * @notice Gets the vault configuration of a supported asset.\\n */\\n function getAssetConfig(address _asset)\\n public\\n view\\n returns (Asset memory config)\\n {\\n config = assets[_asset];\\n }\\n\\n /**\\n * @notice Return all vault asset addresses in order\\n */\\n function getAllAssets() external view returns (address[] memory) {\\n return allAssets;\\n }\\n\\n /**\\n * @notice Return the number of strategies active on the Vault.\\n */\\n function getStrategyCount() external view returns (uint256) {\\n return allStrategies.length;\\n }\\n\\n /**\\n * @notice Return the array of all strategies\\n */\\n function getAllStrategies() external view returns (address[] memory) {\\n return allStrategies;\\n }\\n\\n /**\\n * @notice Returns whether the vault supports the asset\\n * @param _asset address of the asset\\n * @return true if supported\\n */\\n function isSupportedAsset(address _asset) external view returns (bool) {\\n return assets[_asset].isSupported;\\n }\\n\\n /**\\n * @dev Falldown to the admin implementation\\n * @notice This is a catch all for all functions not declared in core\\n */\\n // solhint-disable-next-line no-complex-fallback\\n fallback() external {\\n bytes32 slot = adminImplPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(\\n gas(),\\n sload(slot),\\n 0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n function abs(int256 x) private pure returns (uint256) {\\n require(x < int256(MAX_INT), \\\"Amount too high\\\");\\n return x >= 0 ? uint256(x) : uint256(-x);\\n }\\n}\\n\",\"keccak256\":\"0x5af4c0464b3728750231edf3bec62181c9eb734b5a3b3f7379789c84c0411ef0\",\"license\":\"MIT\"},\"contracts/vault/VaultInitializer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OToken VaultInitializer contract\\n * @notice The Vault contract initializes the vault.\\n * @author Origin Protocol Inc\\n */\\n\\nimport \\\"./VaultStorage.sol\\\";\\n\\ncontract VaultInitializer is VaultStorage {\\n function initialize(address _priceProvider, address _oToken)\\n external\\n onlyGovernor\\n initializer\\n {\\n require(_priceProvider != address(0), \\\"PriceProvider address is zero\\\");\\n require(_oToken != address(0), \\\"oToken address is zero\\\");\\n\\n oUSD = OUSD(_oToken);\\n\\n priceProvider = _priceProvider;\\n\\n rebasePaused = false;\\n capitalPaused = true;\\n\\n // Initial redeem fee of 0 basis points\\n redeemFeeBps = 0;\\n // Initial Vault buffer of 0%\\n vaultBuffer = 0;\\n // Initial allocate threshold of 25,000 OUSD\\n autoAllocateThreshold = 25000e18;\\n // Threshold for rebasing\\n rebaseThreshold = 1000e18;\\n // Initialize all strategies\\n allStrategies = new address[](0);\\n }\\n}\\n\",\"keccak256\":\"0x5b9676307bbabe14b5278f00ec7edc557b84debbfa1391902d78100cb9cd467e\",\"license\":\"MIT\"},\"contracts/vault/VaultStorage.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title OToken VaultStorage contract\\n * @notice The VaultStorage contract defines the storage for the Vault contracts\\n * @author Origin Protocol Inc\\n */\\n\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport { IStrategy } from \\\"../interfaces/IStrategy.sol\\\";\\nimport { Governable } from \\\"../governance/Governable.sol\\\";\\nimport { OUSD } from \\\"../token/OUSD.sol\\\";\\nimport { Initializable } from \\\"../utils/Initializable.sol\\\";\\nimport \\\"../utils/Helpers.sol\\\";\\n\\ncontract VaultStorage is Initializable, Governable {\\n using SafeERC20 for IERC20;\\n\\n event AssetSupported(address _asset);\\n event AssetDefaultStrategyUpdated(address _asset, address _strategy);\\n event AssetAllocated(address _asset, address _strategy, uint256 _amount);\\n event StrategyApproved(address _addr);\\n event StrategyRemoved(address _addr);\\n event Mint(address _addr, uint256 _value);\\n event Redeem(address _addr, uint256 _value);\\n event CapitalPaused();\\n event CapitalUnpaused();\\n event RebasePaused();\\n event RebaseUnpaused();\\n event VaultBufferUpdated(uint256 _vaultBuffer);\\n event OusdMetaStrategyUpdated(address _ousdMetaStrategy);\\n event RedeemFeeUpdated(uint256 _redeemFeeBps);\\n event PriceProviderUpdated(address _priceProvider);\\n event AllocateThresholdUpdated(uint256 _threshold);\\n event RebaseThresholdUpdated(uint256 _threshold);\\n event StrategistUpdated(address _address);\\n event MaxSupplyDiffChanged(uint256 maxSupplyDiff);\\n event YieldDistribution(address _to, uint256 _yield, uint256 _fee);\\n event TrusteeFeeBpsChanged(uint256 _basis);\\n event TrusteeAddressChanged(address _address);\\n event NetOusdMintForStrategyThresholdChanged(uint256 _threshold);\\n event SwapperChanged(address _address);\\n event SwapAllowedUndervalueChanged(uint256 _basis);\\n event SwapSlippageChanged(address _asset, uint256 _basis);\\n event Swapped(\\n address indexed _fromAsset,\\n address indexed _toAsset,\\n uint256 _fromAssetAmount,\\n uint256 _toAssetAmount\\n );\\n\\n // Assets supported by the Vault, i.e. Stablecoins\\n enum UnitConversion {\\n DECIMALS,\\n GETEXCHANGERATE\\n }\\n // Changed to fit into a single storage slot so the decimals needs to be recached\\n struct Asset {\\n // Note: OETHVaultCore doesn't use `isSupported` when minting,\\n // redeeming or checking balance of assets.\\n bool isSupported;\\n UnitConversion unitConversion;\\n uint8 decimals;\\n // Max allowed slippage from the Oracle price when swapping collateral assets in basis points.\\n // For example 40 == 0.4% slippage\\n uint16 allowedOracleSlippageBps;\\n }\\n\\n /// @dev mapping of supported vault assets to their configuration\\n // slither-disable-next-line uninitialized-state\\n mapping(address => Asset) internal assets;\\n /// @dev list of all assets supported by the vault.\\n // slither-disable-next-line uninitialized-state\\n address[] internal allAssets;\\n\\n // Strategies approved for use by the Vault\\n struct Strategy {\\n bool isSupported;\\n uint256 _deprecated; // Deprecated storage slot\\n }\\n /// @dev mapping of strategy contracts to their configiration\\n mapping(address => Strategy) internal strategies;\\n /// @dev list of all vault strategies\\n address[] internal allStrategies;\\n\\n /// @notice Address of the Oracle price provider contract\\n // slither-disable-next-line uninitialized-state\\n address public priceProvider;\\n /// @notice pause rebasing if true\\n bool public rebasePaused = false;\\n /// @notice pause operations that change the OToken supply.\\n /// eg mint, redeem, allocate, mint/burn for strategy\\n bool public capitalPaused = true;\\n /// @notice Redemption fee in basis points. eg 50 = 0.5%\\n uint256 public redeemFeeBps;\\n /// @notice Percentage of assets to keep in Vault to handle (most) withdrawals. 100% = 1e18.\\n uint256 public vaultBuffer;\\n /// @notice OToken mints over this amount automatically allocate funds. 18 decimals.\\n uint256 public autoAllocateThreshold;\\n /// @notice OToken mints over this amount automatically rebase. 18 decimals.\\n uint256 public rebaseThreshold;\\n\\n /// @dev Address of the OToken token. eg OUSD or OETH.\\n // slither-disable-next-line uninitialized-state\\n OUSD internal oUSD;\\n\\n //keccak256(\\\"OUSD.vault.governor.admin.impl\\\");\\n bytes32 constant adminImplPosition =\\n 0xa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9;\\n\\n // Address of the contract responsible for post rebase syncs with AMMs\\n address private _deprecated_rebaseHooksAddr = address(0);\\n\\n // Deprecated: Address of Uniswap\\n // slither-disable-next-line constable-states\\n address private _deprecated_uniswapAddr = address(0);\\n\\n /// @notice Address of the Strategist\\n address public strategistAddr = address(0);\\n\\n /// @notice Mapping of asset address to the Strategy that they should automatically\\n // be allocated to\\n // slither-disable-next-line uninitialized-state\\n mapping(address => address) public assetDefaultStrategies;\\n\\n /// @notice Max difference between total supply and total value of assets. 18 decimals.\\n // slither-disable-next-line uninitialized-state\\n uint256 public maxSupplyDiff;\\n\\n /// @notice Trustee contract that can collect a percentage of yield\\n address public trusteeAddress;\\n\\n /// @notice Amount of yield collected in basis points. eg 2000 = 20%\\n uint256 public trusteeFeeBps;\\n\\n /// @dev Deprecated: Tokens that should be swapped for stablecoins\\n address[] private _deprecated_swapTokens;\\n\\n uint256 constant MINT_MINIMUM_UNIT_PRICE = 0.998e18;\\n\\n /// @notice Metapool strategy that is allowed to mint/burn OTokens without changing collateral\\n address public ousdMetaStrategy = address(0);\\n\\n /// @notice How much OTokens are currently minted by the strategy\\n int256 public netOusdMintedForStrategy = 0;\\n\\n /// @notice How much net total OTokens are allowed to be minted by all strategies\\n uint256 public netOusdMintForStrategyThreshold = 0;\\n\\n uint256 constant MIN_UNIT_PRICE_DRIFT = 0.7e18;\\n uint256 constant MAX_UNIT_PRICE_DRIFT = 1.3e18;\\n\\n /// @notice Collateral swap configuration.\\n /// @dev is packed into a single storage slot to save gas.\\n struct SwapConfig {\\n // Contract that swaps the vault's collateral assets\\n address swapper;\\n // Max allowed percentage the total value can drop below the total supply in basis points.\\n // For example 100 == 1%\\n uint16 allowedUndervalueBps;\\n }\\n SwapConfig internal swapConfig = SwapConfig(address(0), 0);\\n\\n // For future use\\n uint256[50] private __gap;\\n\\n /**\\n * @notice set the implementation for the admin, this needs to be in a base class else we cannot set it\\n * @param newImpl address of the implementation\\n */\\n function setAdminImpl(address newImpl) external onlyGovernor {\\n require(\\n Address.isContract(newImpl),\\n \\\"new implementation is not a contract\\\"\\n );\\n bytes32 position = adminImplPosition;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(position, newImpl)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbcefeb5e2b88d99a54dbe6542dc25d0a68eeaf3adfe6e12fb70049cc024b1a79\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6037805461ffff60a01b1916600160a81b179055603d80546001600160a01b0319908116909155603e805482169055603f80548216905560458054909116905560006046819055604781905560e060405260a081905260c052604880546001600160b01b03191690553480156200007557600080fd5b50604051620036453803806200364583398101604081905262000098916200010e565b620000b0336000805160206200362583398151915255565b60008051602062003625833981519152546040516001600160a01b03909116906000907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908290a360601b6001600160601b03191660805262000140565b6000602082840312156200012157600080fd5b81516001600160a01b03811681146200013957600080fd5b9392505050565b60805160601c61348e620001976000396000818161034f0152818161072401528181610797015281816112d001528181611d0301528181611edd01528181611f7101528181611fa70152611ffb015261348e6000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c806367bd7ba311610146578063ab80dafb116100c3578063c7af335211610087578063c7af335214610545578063d38bfff41461054d578063d4c3eea014610560578063e45cc9f014610568578063e6cc543214610571578063fc0cfeee146105855761025e565b8063ab80dafb14610507578063abaa99161461051a578063af14052c14610522578063b888879e1461052a578063c3b288641461053d5761025e565b80638e510b521161010a5780638e510b52146104985780639be918e6146104a15780639fa1826e146104cd578063a0aead4d146104d6578063a403e4d5146104de5761025e565b806367bd7ba3146104295780636ec3ab67146104495780637136a7a6146104695780637a2202f31461047c5780637cbc2373146104855761025e565b806344c54707116101df57806354c6d858116101a357806354c6d858146103cc578063570d8e1d146103d55780635b60f9fc146103e85780635d36b190146103fb5780635f515226146104035780636217f3ea146104165761025e565b806344c5470714610371578063485cc9551461037957806349c1d54d1461038c57806352d38e5d1461039f57806353ca9f24146103a85761025e565b8063207134b011610226578063207134b0146103115780632acada4d1461031a57806331e19cfa1461032f5780633b8fe28d146103375780633fc8cef31461034a5761025e565b806309f6442c146102a45780630c340a24146102c0578063156e29f6146102e057806318ce56bd146102f55780631edfe3da14610308575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e80801561029f573d6000f35b3d6000fd5b6102ad60385481565b6040519081526020015b60405180910390f35b6102c8610598565b6040516001600160a01b0390911681526020016102b7565b6102f36102ee366004612ea1565b6105b5565b005b6045546102c8906001600160a01b031681565b6102ad60395481565b6102ad60435481565b610322610633565b6040516102b79190612f7f565b6036546102ad565b6102ad610345366004612e53565b610695565b6102c87f000000000000000000000000000000000000000000000000000000000000000081565b6102f36106f0565b6102f3610387366004612e6e565b610839565b6042546102c8906001600160a01b031681565b6102ad603b5481565b6037546103bc90600160a01b900460ff1681565b60405190151581526020016102b7565b6102ad607b5481565b603f546102c8906001600160a01b031681565b6102ad6103f6366004612e53565b610a3b565b6102f3610a64565b6102ad610411366004612e53565b610b0a565b6102f3610424366004612ef6565b610b1b565b61043c610437366004612ef6565b610cb2565b6040516102b79190612fcc565b61045c610457366004612e53565b610cbd565b6040516102b7919061312b565b6102f3610477366004612ef6565b610d63565b6102ad60475481565b6102f3610493366004612f28565b610e4e565b6102ad60415481565b6103bc6104af366004612e53565b6001600160a01b031660009081526033602052604090205460ff1690565b6102ad603a5481565b6034546102ad565b6102c86104ec366004612e53565b6040602081905260009182529020546001600160a01b031681565b6102f3610515366004612ef6565b610ec1565b6102f3611038565b6102f36110a7565b6037546102c8906001600160a01b031681565b6103226110ed565b6103bc61114d565b6102f361055b366004612e53565b61117e565b6102ad611222565b6102ad60465481565b6037546103bc90600160a81b900460ff1681565b6102f3610593366004612e53565b61122c565b60006105b06000805160206134398339815191525490565b905090565b603754600160a81b900460ff16156105e85760405162461bcd60e51b81526004016105df906130db565b60405180910390fd5b6000805160206134198339815191528054600281141561061a5760405162461bcd60e51b81526004016105df90613103565b600282556106298585856112ce565b5060019055505050565b6060603480548060200260200160405190810160405280929190818152602001828054801561068b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161066d575b5050505050905090565b6000806106be6106b86106a7856114de565b670de0b6b3a7640000906012611548565b846115aa565b9050670de0b6b3a7640000816106d5856001611706565b6106df91906132e7565b6106e991906131da565b9392505050565b6106f861114d565b6107145760405162461bcd60e51b81526004016105df9061307b565b60345460005b81811015610794577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166034828154811061075f5761075f6133ec565b6000918252602090912001546001600160a01b0316141561078457607b819055610794565b61078d81613388565b905061071a565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166034607b54815481106107d4576107d46133ec565b6000918252602090912001546001600160a01b0316146108365760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964205745544820417373657420496e646578000000000000000060448201526064016105df565b50565b61084161114d565b61085d5760405162461bcd60e51b81526004016105df9061307b565b600054610100900460ff1680610876575060005460ff16155b6108d95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105df565b600054610100900460ff161580156108fb576000805461ffff19166101011790555b6001600160a01b0383166109515760405162461bcd60e51b815260206004820152601d60248201527f507269636550726f76696465722061646472657373206973207a65726f00000060448201526064016105df565b6001600160a01b0382166109a05760405162461bcd60e51b81526020600482015260166024820152756f546f6b656e2061646472657373206973207a65726f60501b60448201526064016105df565b603c80546001600160a01b038481166001600160a01b031990921691909117909155603780546001600160b01b03191691851691909117600160a81b17905560006038819055603981905569054b40b1f852bda00000603a55683635c9adc5dea00000603b556040805191825260208201908190529051610a2391603691612dcb565b508015610a36576000805461ff00191690555b505050565b600080610a4d6106b86106a7856114de565b9050670de0b6b3a7640000816106d5856000611706565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610aff5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b60648201526084016105df565b610b08336119f8565b565b6000610b1582611ab9565b92915050565b603754600160a81b900460ff1615610b455760405162461bcd60e51b81526004016105df906130db565b6045546001600160a01b03163314610b6f5760405162461bcd60e51b81526004016105df90613037565b6001600160ff1b038110610b955760405162461bcd60e51b81526004016105df906130b2565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63382604051610bc6929190612f66565b60405180910390a18060466000828254610be09190613306565b9091555050604754604654610bf490611c88565b10610c4b5760405162461bcd60e51b815260206004820152602160248201527f417474656d7074696e6720746f206275726e20746f6f206d756368204f5553446044820152601760f91b60648201526084016105df565b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610c7d9033908590600401612f66565b600060405180830381600087803b158015610c9757600080fd5b505af1158015610cab573d6000803e3d6000fd5b5050505050565b6060610b1582611ccb565b604080516080808201835260008083526020808401829052838501829052606084018290526001600160a01b038616825260338152908490208451928301909452835460ff808216151584529394929391840191610100909104166001811115610d2957610d296133d6565b6001811115610d3a57610d3a6133d6565b8152905462010000810460ff1660208301526301000000900461ffff1660409091015292915050565b603754600160a81b900460ff1615610d8d5760405162461bcd60e51b81526004016105df906130db565b60008051602061341983398151915280546002811415610dbf5760405162461bcd60e51b81526004016105df90613103565b60028255603c546040516370a0823160e01b8152336004820152610e46916001600160a01b0316906370a082319060240160206040518083038186803b158015610e0857600080fd5b505afa158015610e1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e409190612f0f565b84611e0c565b506001905550565b603754600160a81b900460ff1615610e785760405162461bcd60e51b81526004016105df906130db565b60008051602061341983398151915280546002811415610eaa5760405162461bcd60e51b81526004016105df90613103565b60028255610eb88484611e0c565b50600190555050565b603754600160a81b900460ff1615610eeb5760405162461bcd60e51b81526004016105df906130db565b6045546001600160a01b03163314610f155760405162461bcd60e51b81526004016105df90613037565b6001600160ff1b038110610f3b5760405162461bcd60e51b81526004016105df906130b2565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853382604051610f6c929190612f66565b60405180910390a18060466000828254610f869190613181565b9091555050604754604654610f9a90611c88565b106110065760405162461bcd60e51b815260206004820152603660248201527f4d696e746564206f75736420737572706173736564206e65744f7573644d696e6044820152753a2337b929ba3930ba32b3bcaa343932b9b437b6321760511b60648201526084016105df565b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610c7d9033908590600401612f66565b603754600160a81b900460ff16156110625760405162461bcd60e51b81526004016105df906130db565b600080516020613419833981519152805460028114156110945760405162461bcd60e51b81526004016105df90613103565b600282556110a0612118565b5060019055565b600080516020613419833981519152805460028114156110d95760405162461bcd60e51b81526004016105df90613103565b600282556110e561238c565b505060019055565b6060603680548060200260200160405190810160405280929190818152602001828054801561068b576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161066d575050505050905090565b60006111656000805160206134398339815191525490565b6001600160a01b0316336001600160a01b031614905090565b61118661114d565b6111a25760405162461bcd60e51b81526004016105df9061307b565b6111ca817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b03166111ea6000805160206134398339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006105b06126c7565b61123461114d565b6112505760405162461bcd60e51b81526004016105df9061307b565b803b6112aa5760405162461bcd60e51b8152602060048201526024808201527f6e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e746044820152631c9858dd60e21b60648201526084016105df565b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461134f5760405162461bcd60e51b815260206004820152601d60248201527f556e737570706f7274656420617373657420666f72206d696e74696e6700000060448201526064016105df565b6000821161139f5760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016105df565b808210156113ef5760405162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d000060448201526064016105df565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853383604051611420929190612f66565b60405180910390a1603754600160a01b900460ff161580156114445750603b548210155b156114535761145161238c565b505b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906114859033908690600401612f66565b600060405180830381600087803b15801561149f57600080fd5b505af11580156114b3573d6000803e3d6000fd5b506114cd925050506001600160a01b0384163330856126e3565b603a548210610a3657610a36612118565b6001600160a01b03811660009081526033602052604090205462010000900460ff16806115435760405162461bcd60e51b8152602060048201526013602482015272111958da5b585b1cc81b9bdd0818d858da1959606a1b60448201526064016105df565b919050565b6000818311156115785761157161155f8385613345565b61156a90600a61323f565b859061274e565b93506115a2565b818310156115a25761159f61158d8484613345565b61159890600a61323f565b859061275a565b93505b509192915050565b6001600160a01b038116600090815260336020526040812054610100900460ff16818160018111156115de576115de6133d6565b1415611602576115fa60126115f2856114de565b869190611548565b915050610b15565b6001816001811115611616576116166133d6565b14156116b7576000836001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561165757600080fd5b505afa15801561166b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168f9190612f0f565b9050670de0b6b3a76400006116a482876132e7565b6116ae91906131da565b92505050610b15565b60405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105df565b5092915050565b6001600160a01b038281166000818152603360205260408082205460375491516315d5220f60e31b81526004810194909452919361010090920460ff169291169063aea910789060240160206040518083038186803b15801561176857600080fd5b505afa15801561177c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a09190612f0f565b915060018160018111156117b6576117b66133d6565b1415611856576000846001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117f757600080fd5b505afa15801561180b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182f9190612f0f565b90508061184484670de0b6b3a76400006132e7565b61184e91906131da565b9250506118b7565b600081600181111561186a5761186a6133d6565b146118b75760405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105df565b67120a871cc002000082111561190f5760405162461bcd60e51b815260206004820152601860248201527f5661756c743a2050726963652065786365656473206d6178000000000000000060448201526064016105df565b6709b6e64a8ec600008210156119605760405162461bcd60e51b81526020600482015260166024820152752b30bab63a1d10283934b1b2903ab73232b91036b4b760511b60448201526064016105df565b82156119d757670de0b6b3a764000082111561198257670de0b6b3a764000091505b670dd99bb65dd700008210156119d25760405162461bcd60e51b815260206004820152601560248201527441737365742070726963652062656c6f772070656760581b60448201526064016105df565b6116ff565b670de0b6b3a76400008210156116ff5750670de0b6b3a76400009392505050565b6001600160a01b038116611a4e5760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f72206973206164647265737328302900000000000060448201526064016105df565b806001600160a01b0316611a6e6000805160206134398339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36108368160008051602061343983398151915255565b6040516370a0823160e01b815230600482015260009082906001600160a01b038216906370a082319060240160206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b359190612f0f565b60365490925060005b81811015611c8057600060368281548110611b5b57611b5b6133ec565b60009182526020909120015460405163551c457b60e11b81526001600160a01b0388811660048301529091169150819063aa388af69060240160206040518083038186803b158015611bac57600080fd5b505afa158015611bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be49190612ed4565b15611c6f57604051632fa8a91360e11b81526001600160a01b038781166004830152821690635f5152269060240160206040518083038186803b158015611c2a57600080fd5b505afa158015611c3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c629190612f0f565b611c6c90866131c2565b94505b50611c7981613388565b9050611b3e565b505050919050565b60006001600160ff1b038212611cb05760405162461bcd60e51b81526004016105df906130b2565b6000821215611cc757611cc2826133a3565b610b15565b5090565b60385460609015611cfa57603854600090611cea908490612710612766565b9050611cf68184613345565b9250505b6000607b5490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660348281548110611d3e57611d3e6133ec565b6000918252602090912001546001600160a01b031614611da05760405162461bcd60e51b815260206004820152601b60248201527f5745544820417373657420696e646578206e6f7420636163686564000000000060448201526064016105df565b60345467ffffffffffffffff811115611dbb57611dbb613402565b604051908082528060200260200182016040528015611de4578160200160208202803683370190505b50915082828281518110611dfa57611dfa6133ec565b60200260200101818152505050919050565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63383604051611e3d929190612f66565b60405180910390a181611e4e575050565b6000611e5983611ccb565b607b5481518110611e6c57611e6c6133ec565b6020026020010151905081811015611ec65760405162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d60448201526064016105df565b6040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611f2757600080fd5b505afa158015611f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5f9190612f0f565b10611f9d57611f986001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383612788565b6120ab565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660009081526040602081905290205416801561206f57604051636ce5768960e11b81523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301526044820184905282919082169063d9caed1290606401600060405180830381600087803b15801561205157600080fd5b505af1158015612065573d6000803e3d6000fd5b50505050506120a9565b60405162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b60448201526064016105df565b505b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac906120dd9033908790600401612f66565b600060405180830381600087803b1580156120f757600080fd5b505af115801561210b573d6000803e3d6000fd5b50505050610a36836127a7565b600061212261290d565b90508061212c5750565b60006121366129ef565b9050600061214482846131c2565b90506000826121695760395461216290670de0b6b3a7640000613345565b90506121ac565b838260395461217891906132e7565b61218291906131da565b905080670de0b6b3a764000011156121a65761216281670de0b6b3a7640000613345565b50505050565b806121b75750505050565b60345460005b81811015612384576000603482815481106121da576121da6133ec565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b15801561222857600080fd5b505afa15801561223c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122609190612f0f565b90508061226e575050612374565b600061227a8287612a4b565b6001600160a01b038085166000908152604060208190529020549192501680158015906122a75750600082115b1561236f57806122c16001600160a01b0386168285612788565b6040516311f9fbc960e21b81526001600160a01b038216906347e7ef24906122ef9088908790600401612f66565b600060405180830381600087803b15801561230957600080fd5b505af115801561231d573d6000803e3d6000fd5b5050604080516001600160a01b03808a168252861660208201529081018690527f41b99659f6ba0803f444aff29e5bf6e26dd86a3219aff92119d69710a956ba8d9250606001905060405180910390a1505b505050505b61237d81613388565b90506121bd565b505050505050565b603754600090600160a01b900460ff16156123db5760405162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b60448201526064016105df565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561242057600080fd5b505afa158015612434573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124589190612f0f565b905060006124646126c7565b9050816124745791506126c49050565b6042546001600160a01b0316801580159061248e57508282115b156125d057600061249f8484613345565b905060006124bc604354612710846127669092919063ffffffff16565b90508082116125185760405162461bcd60e51b815260206004820152602260248201527f466565206d757374206e6f742062652067726561746572207468616e207969656044820152611b1960f21b60648201526084016105df565b801561258357603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906125509086908590600401612f66565b600060405180830381600087803b15801561256a57600080fd5b505af115801561257e573d6000803e3d6000fd5b505050505b604080516001600160a01b0385168152602081018490529081018290527f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809060600160405180910390a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561261e57600080fd5b505afa158015612632573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126569190612f0f565b9250828211156126bf57603c546040516339a7919f60e01b8152600481018490526001600160a01b03909116906339a7919f90602401600060405180830381600087803b1580156126a657600080fd5b505af11580156126ba573d6000803e3d6000fd5b505050505b509150505b90565b60006126d16129ef565b6126d961290d565b6105b091906131c2565b6040516001600160a01b03808516602483015283166044820152606481018290526121a69085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a60565b60006106e982846132e7565b60006106e982846131da565b600080612773858561274e565b905061277f818461275a565b95945050505050565b610a368363a9059cbb60e01b8484604051602401612717929190612f66565b6000603b5482101580156127c55750603754600160a01b900460ff16155b156127d9576127d261238c565b90506127e4565b6127e16126c7565b90505b6041541561290957600061287e82603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128789190612f0f565b90612b32565b9050604154670de0b6b3a764000082116128a9576128a482670de0b6b3a7640000613345565b6128bb565b6128bb670de0b6b3a764000083613345565b1115610a365760405162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f72000060448201526064016105df565b5050565b603454600090815b818110156129ea57600060348281548110612932576129326133ec565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b15801561298057600080fd5b505afa158015612994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b89190612f0f565b905080156129d7576129ca81836115aa565b6129d490866131c2565b94505b5050806129e390613388565b9050612915565b505090565b603654600090815b818110156129ea57612a2f60368281548110612a1557612a156133ec565b6000918252602090912001546001600160a01b0316612b5b565b612a3990846131c2565b9250612a4481613388565b90506129f7565b60006106e98383670de0b6b3a7640000612766565b6000612ab5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cc09092919063ffffffff16565b805190915015610a365780806020019051810190612ad39190612ed4565b610a365760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105df565b600080612b4784670de0b6b3a764000061274e565b9050612b53818461275a565b949350505050565b6034546000908290825b81811015611c8057600060348281548110612b8257612b826133ec565b60009182526020909120015460405163551c457b60e11b81526001600160a01b039182166004820181905292509085169063aa388af69060240160206040518083038186803b158015612bd457600080fd5b505afa158015612be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c0c9190612ed4565b15612caf57604051632fa8a91360e11b81526001600160a01b03828116600483015260009190861690635f5152269060240160206040518083038186803b158015612c5657600080fd5b505afa158015612c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8e9190612f0f565b90508015612cad57612ca081836115aa565b612caa90876131c2565b95505b505b50612cb981613388565b9050612b65565b6060612b53848460008585843b612d195760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105df565b600080866001600160a01b03168587604051612d359190612f4a565b60006040518083038185875af1925050503d8060008114612d72576040519150601f19603f3d011682016040523d82523d6000602084013e612d77565b606091505b5091509150612d87828286612d92565b979650505050505050565b60608315612da15750816106e9565b825115612db15782518084602001fd5b8160405162461bcd60e51b81526004016105df9190613004565b828054828255906000526020600020908101928215612e20579160200282015b82811115612e2057825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612deb565b50611cc79291505b80821115611cc75760008155600101612e28565b80356001600160a01b038116811461154357600080fd5b600060208284031215612e6557600080fd5b6106e982612e3c565b60008060408385031215612e8157600080fd5b612e8a83612e3c565b9150612e9860208401612e3c565b90509250929050565b600080600060608486031215612eb657600080fd5b612ebf84612e3c565b95602085013595506040909401359392505050565b600060208284031215612ee657600080fd5b815180151581146106e957600080fd5b600060208284031215612f0857600080fd5b5035919050565b600060208284031215612f2157600080fd5b5051919050565b60008060408385031215612f3b57600080fd5b50508035926020909101359150565b60008251612f5c81846020870161335c565b9190910192915050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015612fc05783516001600160a01b031683529284019291840191600101612f9b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612fc057835183529284019291840191600101612fe8565b602081526000825180602084015261302381604085016020870161335c565b601f01601f19169190910160400192915050565b60208082526024908201527f43616c6c6572206973206e6f7420746865204f555344206d65746120737472616040820152637465677960e01b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252600f908201526e082dadeeadce840e8dede40d0d2ced608b1b604082015260600190565b6020808252600e908201526d10d85c1a5d185b081c185d5cd95960921b604082015260600190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b815115158152602082015160808201906002811061315957634e487b7160e01b600052602160045260246000fd5b8060208401525060ff604084015116604083015261ffff606084015116606083015292915050565b600080821280156001600160ff1b03849003851316156131a3576131a36133c0565b600160ff1b83900384128116156131bc576131bc6133c0565b50500190565b600082198211156131d5576131d56133c0565b500190565b6000826131f757634e487b7160e01b600052601260045260246000fd5b500490565b600181815b8085111561323757816000190482111561321d5761321d6133c0565b8085161561322a57918102915b93841c9390800290613201565b509250929050565b60006106e9838360008261325557506001610b15565b8161326257506000610b15565b816001811461327857600281146132825761329e565b6001915050610b15565b60ff841115613293576132936133c0565b50506001821b610b15565b5060208310610133831016604e8410600b84101617156132c1575081810a610b15565b6132cb83836131fc565b80600019048211156132df576132df6133c0565b029392505050565b6000816000190483118215151615613301576133016133c0565b500290565b60008083128015600160ff1b850184121615613324576133246133c0565b6001600160ff1b038401831381161561333f5761333f6133c0565b50500390565b600082821015613357576133576133c0565b500390565b60005b8381101561337757818101518382015260200161335f565b838111156121a65750506000910152565b600060001982141561339c5761339c6133c0565b5060010190565b6000600160ff1b8214156133b9576133b96133c0565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa26469706673582212204e8e456474cb6e24f080768f1c492c792431f05e2e92233405d5b9337a2458fb64736f6c634300080700337bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061025e5760003560e01c806367bd7ba311610146578063ab80dafb116100c3578063c7af335211610087578063c7af335214610545578063d38bfff41461054d578063d4c3eea014610560578063e45cc9f014610568578063e6cc543214610571578063fc0cfeee146105855761025e565b8063ab80dafb14610507578063abaa99161461051a578063af14052c14610522578063b888879e1461052a578063c3b288641461053d5761025e565b80638e510b521161010a5780638e510b52146104985780639be918e6146104a15780639fa1826e146104cd578063a0aead4d146104d6578063a403e4d5146104de5761025e565b806367bd7ba3146104295780636ec3ab67146104495780637136a7a6146104695780637a2202f31461047c5780637cbc2373146104855761025e565b806344c54707116101df57806354c6d858116101a357806354c6d858146103cc578063570d8e1d146103d55780635b60f9fc146103e85780635d36b190146103fb5780635f515226146104035780636217f3ea146104165761025e565b806344c5470714610371578063485cc9551461037957806349c1d54d1461038c57806352d38e5d1461039f57806353ca9f24146103a85761025e565b8063207134b011610226578063207134b0146103115780632acada4d1461031a57806331e19cfa1461032f5780633b8fe28d146103375780633fc8cef31461034a5761025e565b806309f6442c146102a45780630c340a24146102c0578063156e29f6146102e057806318ce56bd146102f55780631edfe3da14610308575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e80801561029f573d6000f35b3d6000fd5b6102ad60385481565b6040519081526020015b60405180910390f35b6102c8610598565b6040516001600160a01b0390911681526020016102b7565b6102f36102ee366004612ea1565b6105b5565b005b6045546102c8906001600160a01b031681565b6102ad60395481565b6102ad60435481565b610322610633565b6040516102b79190612f7f565b6036546102ad565b6102ad610345366004612e53565b610695565b6102c87f000000000000000000000000000000000000000000000000000000000000000081565b6102f36106f0565b6102f3610387366004612e6e565b610839565b6042546102c8906001600160a01b031681565b6102ad603b5481565b6037546103bc90600160a01b900460ff1681565b60405190151581526020016102b7565b6102ad607b5481565b603f546102c8906001600160a01b031681565b6102ad6103f6366004612e53565b610a3b565b6102f3610a64565b6102ad610411366004612e53565b610b0a565b6102f3610424366004612ef6565b610b1b565b61043c610437366004612ef6565b610cb2565b6040516102b79190612fcc565b61045c610457366004612e53565b610cbd565b6040516102b7919061312b565b6102f3610477366004612ef6565b610d63565b6102ad60475481565b6102f3610493366004612f28565b610e4e565b6102ad60415481565b6103bc6104af366004612e53565b6001600160a01b031660009081526033602052604090205460ff1690565b6102ad603a5481565b6034546102ad565b6102c86104ec366004612e53565b6040602081905260009182529020546001600160a01b031681565b6102f3610515366004612ef6565b610ec1565b6102f3611038565b6102f36110a7565b6037546102c8906001600160a01b031681565b6103226110ed565b6103bc61114d565b6102f361055b366004612e53565b61117e565b6102ad611222565b6102ad60465481565b6037546103bc90600160a81b900460ff1681565b6102f3610593366004612e53565b61122c565b60006105b06000805160206134398339815191525490565b905090565b603754600160a81b900460ff16156105e85760405162461bcd60e51b81526004016105df906130db565b60405180910390fd5b6000805160206134198339815191528054600281141561061a5760405162461bcd60e51b81526004016105df90613103565b600282556106298585856112ce565b5060019055505050565b6060603480548060200260200160405190810160405280929190818152602001828054801561068b57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161066d575b5050505050905090565b6000806106be6106b86106a7856114de565b670de0b6b3a7640000906012611548565b846115aa565b9050670de0b6b3a7640000816106d5856001611706565b6106df91906132e7565b6106e991906131da565b9392505050565b6106f861114d565b6107145760405162461bcd60e51b81526004016105df9061307b565b60345460005b81811015610794577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166034828154811061075f5761075f6133ec565b6000918252602090912001546001600160a01b0316141561078457607b819055610794565b61078d81613388565b905061071a565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166034607b54815481106107d4576107d46133ec565b6000918252602090912001546001600160a01b0316146108365760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964205745544820417373657420496e646578000000000000000060448201526064016105df565b50565b61084161114d565b61085d5760405162461bcd60e51b81526004016105df9061307b565b600054610100900460ff1680610876575060005460ff16155b6108d95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016105df565b600054610100900460ff161580156108fb576000805461ffff19166101011790555b6001600160a01b0383166109515760405162461bcd60e51b815260206004820152601d60248201527f507269636550726f76696465722061646472657373206973207a65726f00000060448201526064016105df565b6001600160a01b0382166109a05760405162461bcd60e51b81526020600482015260166024820152756f546f6b656e2061646472657373206973207a65726f60501b60448201526064016105df565b603c80546001600160a01b038481166001600160a01b031990921691909117909155603780546001600160b01b03191691851691909117600160a81b17905560006038819055603981905569054b40b1f852bda00000603a55683635c9adc5dea00000603b556040805191825260208201908190529051610a2391603691612dcb565b508015610a36576000805461ff00191690555b505050565b600080610a4d6106b86106a7856114de565b9050670de0b6b3a7640000816106d5856000611706565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610aff5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b60648201526084016105df565b610b08336119f8565b565b6000610b1582611ab9565b92915050565b603754600160a81b900460ff1615610b455760405162461bcd60e51b81526004016105df906130db565b6045546001600160a01b03163314610b6f5760405162461bcd60e51b81526004016105df90613037565b6001600160ff1b038110610b955760405162461bcd60e51b81526004016105df906130b2565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63382604051610bc6929190612f66565b60405180910390a18060466000828254610be09190613306565b9091555050604754604654610bf490611c88565b10610c4b5760405162461bcd60e51b815260206004820152602160248201527f417474656d7074696e6720746f206275726e20746f6f206d756368204f5553446044820152601760f91b60648201526084016105df565b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610c7d9033908590600401612f66565b600060405180830381600087803b158015610c9757600080fd5b505af1158015610cab573d6000803e3d6000fd5b5050505050565b6060610b1582611ccb565b604080516080808201835260008083526020808401829052838501829052606084018290526001600160a01b038616825260338152908490208451928301909452835460ff808216151584529394929391840191610100909104166001811115610d2957610d296133d6565b6001811115610d3a57610d3a6133d6565b8152905462010000810460ff1660208301526301000000900461ffff1660409091015292915050565b603754600160a81b900460ff1615610d8d5760405162461bcd60e51b81526004016105df906130db565b60008051602061341983398151915280546002811415610dbf5760405162461bcd60e51b81526004016105df90613103565b60028255603c546040516370a0823160e01b8152336004820152610e46916001600160a01b0316906370a082319060240160206040518083038186803b158015610e0857600080fd5b505afa158015610e1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e409190612f0f565b84611e0c565b506001905550565b603754600160a81b900460ff1615610e785760405162461bcd60e51b81526004016105df906130db565b60008051602061341983398151915280546002811415610eaa5760405162461bcd60e51b81526004016105df90613103565b60028255610eb88484611e0c565b50600190555050565b603754600160a81b900460ff1615610eeb5760405162461bcd60e51b81526004016105df906130db565b6045546001600160a01b03163314610f155760405162461bcd60e51b81526004016105df90613037565b6001600160ff1b038110610f3b5760405162461bcd60e51b81526004016105df906130b2565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853382604051610f6c929190612f66565b60405180910390a18060466000828254610f869190613181565b9091555050604754604654610f9a90611c88565b106110065760405162461bcd60e51b815260206004820152603660248201527f4d696e746564206f75736420737572706173736564206e65744f7573644d696e6044820152753a2337b929ba3930ba32b3bcaa343932b9b437b6321760511b60648201526084016105df565b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610c7d9033908590600401612f66565b603754600160a81b900460ff16156110625760405162461bcd60e51b81526004016105df906130db565b600080516020613419833981519152805460028114156110945760405162461bcd60e51b81526004016105df90613103565b600282556110a0612118565b5060019055565b600080516020613419833981519152805460028114156110d95760405162461bcd60e51b81526004016105df90613103565b600282556110e561238c565b505060019055565b6060603680548060200260200160405190810160405280929190818152602001828054801561068b576020028201919060005260206000209081546001600160a01b0316815260019091019060200180831161066d575050505050905090565b60006111656000805160206134398339815191525490565b6001600160a01b0316336001600160a01b031614905090565b61118661114d565b6111a25760405162461bcd60e51b81526004016105df9061307b565b6111ca817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b03166111ea6000805160206134398339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006105b06126c7565b61123461114d565b6112505760405162461bcd60e51b81526004016105df9061307b565b803b6112aa5760405162461bcd60e51b8152602060048201526024808201527f6e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e746044820152631c9858dd60e21b60648201526084016105df565b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461134f5760405162461bcd60e51b815260206004820152601d60248201527f556e737570706f7274656420617373657420666f72206d696e74696e6700000060448201526064016105df565b6000821161139f5760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016105df565b808210156113ef5760405162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d000060448201526064016105df565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853383604051611420929190612f66565b60405180910390a1603754600160a01b900460ff161580156114445750603b548210155b156114535761145161238c565b505b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906114859033908690600401612f66565b600060405180830381600087803b15801561149f57600080fd5b505af11580156114b3573d6000803e3d6000fd5b506114cd925050506001600160a01b0384163330856126e3565b603a548210610a3657610a36612118565b6001600160a01b03811660009081526033602052604090205462010000900460ff16806115435760405162461bcd60e51b8152602060048201526013602482015272111958da5b585b1cc81b9bdd0818d858da1959606a1b60448201526064016105df565b919050565b6000818311156115785761157161155f8385613345565b61156a90600a61323f565b859061274e565b93506115a2565b818310156115a25761159f61158d8484613345565b61159890600a61323f565b859061275a565b93505b509192915050565b6001600160a01b038116600090815260336020526040812054610100900460ff16818160018111156115de576115de6133d6565b1415611602576115fa60126115f2856114de565b869190611548565b915050610b15565b6001816001811115611616576116166133d6565b14156116b7576000836001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561165757600080fd5b505afa15801561166b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168f9190612f0f565b9050670de0b6b3a76400006116a482876132e7565b6116ae91906131da565b92505050610b15565b60405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105df565b5092915050565b6001600160a01b038281166000818152603360205260408082205460375491516315d5220f60e31b81526004810194909452919361010090920460ff169291169063aea910789060240160206040518083038186803b15801561176857600080fd5b505afa15801561177c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a09190612f0f565b915060018160018111156117b6576117b66133d6565b1415611856576000846001600160a01b031663e6aa216c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117f757600080fd5b505afa15801561180b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061182f9190612f0f565b90508061184484670de0b6b3a76400006132e7565b61184e91906131da565b9250506118b7565b600081600181111561186a5761186a6133d6565b146118b75760405162461bcd60e51b815260206004820152601b60248201527f556e737570706f7274656420636f6e76657273696f6e2074797065000000000060448201526064016105df565b67120a871cc002000082111561190f5760405162461bcd60e51b815260206004820152601860248201527f5661756c743a2050726963652065786365656473206d6178000000000000000060448201526064016105df565b6709b6e64a8ec600008210156119605760405162461bcd60e51b81526020600482015260166024820152752b30bab63a1d10283934b1b2903ab73232b91036b4b760511b60448201526064016105df565b82156119d757670de0b6b3a764000082111561198257670de0b6b3a764000091505b670dd99bb65dd700008210156119d25760405162461bcd60e51b815260206004820152601560248201527441737365742070726963652062656c6f772070656760581b60448201526064016105df565b6116ff565b670de0b6b3a76400008210156116ff5750670de0b6b3a76400009392505050565b6001600160a01b038116611a4e5760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f72206973206164647265737328302900000000000060448201526064016105df565b806001600160a01b0316611a6e6000805160206134398339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36108368160008051602061343983398151915255565b6040516370a0823160e01b815230600482015260009082906001600160a01b038216906370a082319060240160206040518083038186803b158015611afd57600080fd5b505afa158015611b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b359190612f0f565b60365490925060005b81811015611c8057600060368281548110611b5b57611b5b6133ec565b60009182526020909120015460405163551c457b60e11b81526001600160a01b0388811660048301529091169150819063aa388af69060240160206040518083038186803b158015611bac57600080fd5b505afa158015611bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be49190612ed4565b15611c6f57604051632fa8a91360e11b81526001600160a01b038781166004830152821690635f5152269060240160206040518083038186803b158015611c2a57600080fd5b505afa158015611c3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c629190612f0f565b611c6c90866131c2565b94505b50611c7981613388565b9050611b3e565b505050919050565b60006001600160ff1b038212611cb05760405162461bcd60e51b81526004016105df906130b2565b6000821215611cc757611cc2826133a3565b610b15565b5090565b60385460609015611cfa57603854600090611cea908490612710612766565b9050611cf68184613345565b9250505b6000607b5490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660348281548110611d3e57611d3e6133ec565b6000918252602090912001546001600160a01b031614611da05760405162461bcd60e51b815260206004820152601b60248201527f5745544820417373657420696e646578206e6f7420636163686564000000000060448201526064016105df565b60345467ffffffffffffffff811115611dbb57611dbb613402565b604051908082528060200260200182016040528015611de4578160200160208202803683370190505b50915082828281518110611dfa57611dfa6133ec565b60200260200101818152505050919050565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63383604051611e3d929190612f66565b60405180910390a181611e4e575050565b6000611e5983611ccb565b607b5481518110611e6c57611e6c6133ec565b6020026020010151905081811015611ec65760405162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d60448201526064016105df565b6040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611f2757600080fd5b505afa158015611f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5f9190612f0f565b10611f9d57611f986001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383612788565b6120ab565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660009081526040602081905290205416801561206f57604051636ce5768960e11b81523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301526044820184905282919082169063d9caed1290606401600060405180830381600087803b15801561205157600080fd5b505af1158015612065573d6000803e3d6000fd5b50505050506120a9565b60405162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b60448201526064016105df565b505b603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac906120dd9033908790600401612f66565b600060405180830381600087803b1580156120f757600080fd5b505af115801561210b573d6000803e3d6000fd5b50505050610a36836127a7565b600061212261290d565b90508061212c5750565b60006121366129ef565b9050600061214482846131c2565b90506000826121695760395461216290670de0b6b3a7640000613345565b90506121ac565b838260395461217891906132e7565b61218291906131da565b905080670de0b6b3a764000011156121a65761216281670de0b6b3a7640000613345565b50505050565b806121b75750505050565b60345460005b81811015612384576000603482815481106121da576121da6133ec565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b15801561222857600080fd5b505afa15801561223c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122609190612f0f565b90508061226e575050612374565b600061227a8287612a4b565b6001600160a01b038085166000908152604060208190529020549192501680158015906122a75750600082115b1561236f57806122c16001600160a01b0386168285612788565b6040516311f9fbc960e21b81526001600160a01b038216906347e7ef24906122ef9088908790600401612f66565b600060405180830381600087803b15801561230957600080fd5b505af115801561231d573d6000803e3d6000fd5b5050604080516001600160a01b03808a168252861660208201529081018690527f41b99659f6ba0803f444aff29e5bf6e26dd86a3219aff92119d69710a956ba8d9250606001905060405180910390a1505b505050505b61237d81613388565b90506121bd565b505050505050565b603754600090600160a01b900460ff16156123db5760405162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b60448201526064016105df565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561242057600080fd5b505afa158015612434573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124589190612f0f565b905060006124646126c7565b9050816124745791506126c49050565b6042546001600160a01b0316801580159061248e57508282115b156125d057600061249f8484613345565b905060006124bc604354612710846127669092919063ffffffff16565b90508082116125185760405162461bcd60e51b815260206004820152602260248201527f466565206d757374206e6f742062652067726561746572207468616e207969656044820152611b1960f21b60648201526084016105df565b801561258357603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906125509086908590600401612f66565b600060405180830381600087803b15801561256a57600080fd5b505af115801561257e573d6000803e3d6000fd5b505050505b604080516001600160a01b0385168152602081018490529081018290527f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809060600160405180910390a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561261e57600080fd5b505afa158015612632573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126569190612f0f565b9250828211156126bf57603c546040516339a7919f60e01b8152600481018490526001600160a01b03909116906339a7919f90602401600060405180830381600087803b1580156126a657600080fd5b505af11580156126ba573d6000803e3d6000fd5b505050505b509150505b90565b60006126d16129ef565b6126d961290d565b6105b091906131c2565b6040516001600160a01b03808516602483015283166044820152606481018290526121a69085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a60565b60006106e982846132e7565b60006106e982846131da565b600080612773858561274e565b905061277f818461275a565b95945050505050565b610a368363a9059cbb60e01b8484604051602401612717929190612f66565b6000603b5482101580156127c55750603754600160a01b900460ff16155b156127d9576127d261238c565b90506127e4565b6127e16126c7565b90505b6041541561290957600061287e82603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128789190612f0f565b90612b32565b9050604154670de0b6b3a764000082116128a9576128a482670de0b6b3a7640000613345565b6128bb565b6128bb670de0b6b3a764000083613345565b1115610a365760405162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f72000060448201526064016105df565b5050565b603454600090815b818110156129ea57600060348281548110612932576129326133ec565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b15801561298057600080fd5b505afa158015612994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b89190612f0f565b905080156129d7576129ca81836115aa565b6129d490866131c2565b94505b5050806129e390613388565b9050612915565b505090565b603654600090815b818110156129ea57612a2f60368281548110612a1557612a156133ec565b6000918252602090912001546001600160a01b0316612b5b565b612a3990846131c2565b9250612a4481613388565b90506129f7565b60006106e98383670de0b6b3a7640000612766565b6000612ab5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cc09092919063ffffffff16565b805190915015610a365780806020019051810190612ad39190612ed4565b610a365760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105df565b600080612b4784670de0b6b3a764000061274e565b9050612b53818461275a565b949350505050565b6034546000908290825b81811015611c8057600060348281548110612b8257612b826133ec565b60009182526020909120015460405163551c457b60e11b81526001600160a01b039182166004820181905292509085169063aa388af69060240160206040518083038186803b158015612bd457600080fd5b505afa158015612be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c0c9190612ed4565b15612caf57604051632fa8a91360e11b81526001600160a01b03828116600483015260009190861690635f5152269060240160206040518083038186803b158015612c5657600080fd5b505afa158015612c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8e9190612f0f565b90508015612cad57612ca081836115aa565b612caa90876131c2565b95505b505b50612cb981613388565b9050612b65565b6060612b53848460008585843b612d195760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105df565b600080866001600160a01b03168587604051612d359190612f4a565b60006040518083038185875af1925050503d8060008114612d72576040519150601f19603f3d011682016040523d82523d6000602084013e612d77565b606091505b5091509150612d87828286612d92565b979650505050505050565b60608315612da15750816106e9565b825115612db15782518084602001fd5b8160405162461bcd60e51b81526004016105df9190613004565b828054828255906000526020600020908101928215612e20579160200282015b82811115612e2057825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612deb565b50611cc79291505b80821115611cc75760008155600101612e28565b80356001600160a01b038116811461154357600080fd5b600060208284031215612e6557600080fd5b6106e982612e3c565b60008060408385031215612e8157600080fd5b612e8a83612e3c565b9150612e9860208401612e3c565b90509250929050565b600080600060608486031215612eb657600080fd5b612ebf84612e3c565b95602085013595506040909401359392505050565b600060208284031215612ee657600080fd5b815180151581146106e957600080fd5b600060208284031215612f0857600080fd5b5035919050565b600060208284031215612f2157600080fd5b5051919050565b60008060408385031215612f3b57600080fd5b50508035926020909101359150565b60008251612f5c81846020870161335c565b9190910192915050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015612fc05783516001600160a01b031683529284019291840191600101612f9b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612fc057835183529284019291840191600101612fe8565b602081526000825180602084015261302381604085016020870161335c565b601f01601f19169190910160400192915050565b60208082526024908201527f43616c6c6572206973206e6f7420746865204f555344206d65746120737472616040820152637465677960e01b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252600f908201526e082dadeeadce840e8dede40d0d2ced608b1b604082015260600190565b6020808252600e908201526d10d85c1a5d185b081c185d5cd95960921b604082015260600190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b815115158152602082015160808201906002811061315957634e487b7160e01b600052602160045260246000fd5b8060208401525060ff604084015116604083015261ffff606084015116606083015292915050565b600080821280156001600160ff1b03849003851316156131a3576131a36133c0565b600160ff1b83900384128116156131bc576131bc6133c0565b50500190565b600082198211156131d5576131d56133c0565b500190565b6000826131f757634e487b7160e01b600052601260045260246000fd5b500490565b600181815b8085111561323757816000190482111561321d5761321d6133c0565b8085161561322a57918102915b93841c9390800290613201565b509250929050565b60006106e9838360008261325557506001610b15565b8161326257506000610b15565b816001811461327857600281146132825761329e565b6001915050610b15565b60ff841115613293576132936133c0565b50506001821b610b15565b5060208310610133831016604e8410600b84101617156132c1575081810a610b15565b6132cb83836131fc565b80600019048211156132df576132df6133c0565b029392505050565b6000816000190483118215151615613301576133016133c0565b500290565b60008083128015600160ff1b850184121615613324576133246133c0565b6001600160ff1b038401831381161561333f5761333f6133c0565b50500390565b600082821015613357576133576133c0565b500390565b60005b8381101561337757818101518382015260200161335f565b838111156121a65750506000910152565b600060001982141561339c5761339c6133c0565b5060010190565b6000600160ff1b8214156133b9576133b96133c0565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa26469706673582212204e8e456474cb6e24f080768f1c492c792431f05e2e92233405d5b9337a2458fb64736f6c63430008070033", "libraries": {}, "devdoc": { "author": "Origin Protocol Inc", @@ -1080,6 +1100,9 @@ "_amount": "Amount of OUSD to burn" } }, + "cacheWETHAssetIndex()": { + "details": "Caches WETH's index in `allAssets` variable. Reduces gas usage by redeem by caching that." + }, "checkBalance(address)": { "params": { "_asset": "Address of asset" @@ -1277,7 +1300,7 @@ "storageLayout": { "storage": [ { - "astId": 38139, + "astId": 39151, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "initialized", "offset": 0, @@ -1285,7 +1308,7 @@ "type": "t_bool" }, { - "astId": 38142, + "astId": 39154, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "initializing", "offset": 1, @@ -1293,7 +1316,7 @@ "type": "t_bool" }, { - "astId": 38182, + "astId": 39194, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "______gap", "offset": 0, @@ -1301,15 +1324,15 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 42504, + "astId": 43801, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "assets", "offset": 0, "slot": "51", - "type": "t_mapping(t_address,t_struct(Asset)42498_storage)" + "type": "t_mapping(t_address,t_struct(Asset)43795_storage)" }, { - "astId": 42508, + "astId": 43805, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "allAssets", "offset": 0, @@ -1317,15 +1340,15 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 42519, + "astId": 43816, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "strategies", "offset": 0, "slot": "53", - "type": "t_mapping(t_address,t_struct(Strategy)42513_storage)" + "type": "t_mapping(t_address,t_struct(Strategy)43810_storage)" }, { - "astId": 42523, + "astId": 43820, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "allStrategies", "offset": 0, @@ -1333,7 +1356,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 42526, + "astId": 43823, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "priceProvider", "offset": 0, @@ -1341,7 +1364,7 @@ "type": "t_address" }, { - "astId": 42530, + "astId": 43827, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "rebasePaused", "offset": 20, @@ -1349,7 +1372,7 @@ "type": "t_bool" }, { - "astId": 42534, + "astId": 43831, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "capitalPaused", "offset": 21, @@ -1357,7 +1380,7 @@ "type": "t_bool" }, { - "astId": 42537, + "astId": 43834, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "redeemFeeBps", "offset": 0, @@ -1365,7 +1388,7 @@ "type": "t_uint256" }, { - "astId": 42540, + "astId": 43837, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "vaultBuffer", "offset": 0, @@ -1373,7 +1396,7 @@ "type": "t_uint256" }, { - "astId": 42543, + "astId": 43840, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "autoAllocateThreshold", "offset": 0, @@ -1381,7 +1404,7 @@ "type": "t_uint256" }, { - "astId": 42546, + "astId": 43843, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "rebaseThreshold", "offset": 0, @@ -1389,15 +1412,15 @@ "type": "t_uint256" }, { - "astId": 42550, + "astId": 43847, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "oUSD", "offset": 0, "slot": "60", - "type": "t_contract(OUSD)36965" + "type": "t_contract(OUSD)37977" }, { - "astId": 42559, + "astId": 43856, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "_deprecated_rebaseHooksAddr", "offset": 0, @@ -1405,7 +1428,7 @@ "type": "t_address" }, { - "astId": 42565, + "astId": 43862, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "_deprecated_uniswapAddr", "offset": 0, @@ -1413,7 +1436,7 @@ "type": "t_address" }, { - "astId": 42572, + "astId": 43869, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "strategistAddr", "offset": 0, @@ -1421,7 +1444,7 @@ "type": "t_address" }, { - "astId": 42577, + "astId": 43874, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "assetDefaultStrategies", "offset": 0, @@ -1429,7 +1452,7 @@ "type": "t_mapping(t_address,t_address)" }, { - "astId": 42580, + "astId": 43877, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "maxSupplyDiff", "offset": 0, @@ -1437,7 +1460,7 @@ "type": "t_uint256" }, { - "astId": 42583, + "astId": 43880, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "trusteeAddress", "offset": 0, @@ -1445,7 +1468,7 @@ "type": "t_address" }, { - "astId": 42586, + "astId": 43883, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "trusteeFeeBps", "offset": 0, @@ -1453,7 +1476,7 @@ "type": "t_uint256" }, { - "astId": 42590, + "astId": 43887, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "_deprecated_swapTokens", "offset": 0, @@ -1461,7 +1484,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 42600, + "astId": 43897, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "ousdMetaStrategy", "offset": 0, @@ -1469,7 +1492,7 @@ "type": "t_address" }, { - "astId": 42604, + "astId": 43901, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "netOusdMintedForStrategy", "offset": 0, @@ -1477,7 +1500,7 @@ "type": "t_int256" }, { - "astId": 42608, + "astId": 43905, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "netOusdMintForStrategyThreshold", "offset": 0, @@ -1485,12 +1508,28 @@ "type": "t_uint256" }, { - "astId": 42629, + "astId": 43926, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "swapConfig", "offset": 0, "slot": "72", - "type": "t_struct(SwapConfig)42619_storage" + "type": "t_struct(SwapConfig)43916_storage" + }, + { + "astId": 43930, + "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", + "label": "__gap", + "offset": 0, + "slot": "73", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 40092, + "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", + "label": "wethAssetIndex", + "offset": 0, + "slot": "123", + "type": "t_uint256" } ], "types": { @@ -1516,12 +1555,12 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(OUSD)36965": { + "t_contract(OUSD)37977": { "encoding": "inplace", "label": "contract OUSD", "numberOfBytes": "20" }, - "t_enum(UnitConversion)42488": { + "t_enum(UnitConversion)43785": { "encoding": "inplace", "label": "enum VaultStorage.UnitConversion", "numberOfBytes": "1" @@ -1538,26 +1577,26 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_address,t_struct(Asset)42498_storage)": { + "t_mapping(t_address,t_struct(Asset)43795_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct VaultStorage.Asset)", "numberOfBytes": "32", - "value": "t_struct(Asset)42498_storage" + "value": "t_struct(Asset)43795_storage" }, - "t_mapping(t_address,t_struct(Strategy)42513_storage)": { + "t_mapping(t_address,t_struct(Strategy)43810_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct VaultStorage.Strategy)", "numberOfBytes": "32", - "value": "t_struct(Strategy)42513_storage" + "value": "t_struct(Strategy)43810_storage" }, - "t_struct(Asset)42498_storage": { + "t_struct(Asset)43795_storage": { "encoding": "inplace", "label": "struct VaultStorage.Asset", "members": [ { - "astId": 42490, + "astId": 43787, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "isSupported", "offset": 0, @@ -1565,15 +1604,15 @@ "type": "t_bool" }, { - "astId": 42493, + "astId": 43790, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "unitConversion", "offset": 1, "slot": "0", - "type": "t_enum(UnitConversion)42488" + "type": "t_enum(UnitConversion)43785" }, { - "astId": 42495, + "astId": 43792, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "decimals", "offset": 2, @@ -1581,7 +1620,7 @@ "type": "t_uint8" }, { - "astId": 42497, + "astId": 43794, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "allowedOracleSlippageBps", "offset": 3, @@ -1591,12 +1630,12 @@ ], "numberOfBytes": "32" }, - "t_struct(Strategy)42513_storage": { + "t_struct(Strategy)43810_storage": { "encoding": "inplace", "label": "struct VaultStorage.Strategy", "members": [ { - "astId": 42510, + "astId": 43807, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "isSupported", "offset": 0, @@ -1604,7 +1643,7 @@ "type": "t_bool" }, { - "astId": 42512, + "astId": 43809, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "_deprecated", "offset": 0, @@ -1614,12 +1653,12 @@ ], "numberOfBytes": "64" }, - "t_struct(SwapConfig)42619_storage": { + "t_struct(SwapConfig)43916_storage": { "encoding": "inplace", "label": "struct VaultStorage.SwapConfig", "members": [ { - "astId": 42616, + "astId": 43913, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "swapper", "offset": 0, @@ -1627,7 +1666,7 @@ "type": "t_address" }, { - "astId": 42618, + "astId": 43915, "contract": "contracts/vault/OETHVaultCore.sol:OETHVaultCore", "label": "allowedUndervalueBps", "offset": 20, diff --git a/contracts/storageLayout/mainnet/OETHVaultCore.json b/contracts/storageLayout/mainnet/OETHVaultCore.json index 4748a2a437..cae8e01c8c 100644 --- a/contracts/storageLayout/mainnet/OETHVaultCore.json +++ b/contracts/storageLayout/mainnet/OETHVaultCore.json @@ -29,9 +29,9 @@ "label": "assets", "offset": 0, "slot": "51", - "type": "t_mapping(t_address,t_struct(Asset)42498_storage)", + "type": "t_mapping(t_address,t_struct(Asset)43795_storage)", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:73" + "src": "contracts/vault/VaultStorage.sol:75" }, { "label": "allAssets", @@ -39,15 +39,15 @@ "slot": "52", "type": "t_array(t_address)dyn_storage", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:75" + "src": "contracts/vault/VaultStorage.sol:78" }, { "label": "strategies", "offset": 0, "slot": "53", - "type": "t_mapping(t_address,t_struct(Strategy)42513_storage)", + "type": "t_mapping(t_address,t_struct(Strategy)43810_storage)", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:83" + "src": "contracts/vault/VaultStorage.sol:86" }, { "label": "allStrategies", @@ -55,7 +55,7 @@ "slot": "54", "type": "t_array(t_address)dyn_storage", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:85" + "src": "contracts/vault/VaultStorage.sol:88" }, { "label": "priceProvider", @@ -63,7 +63,7 @@ "slot": "55", "type": "t_address", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:89" + "src": "contracts/vault/VaultStorage.sol:92" }, { "label": "rebasePaused", @@ -71,7 +71,7 @@ "slot": "55", "type": "t_bool", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:91" + "src": "contracts/vault/VaultStorage.sol:94" }, { "label": "capitalPaused", @@ -79,7 +79,7 @@ "slot": "55", "type": "t_bool", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:94" + "src": "contracts/vault/VaultStorage.sol:97" }, { "label": "redeemFeeBps", @@ -87,7 +87,7 @@ "slot": "56", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:96" + "src": "contracts/vault/VaultStorage.sol:99" }, { "label": "vaultBuffer", @@ -95,7 +95,7 @@ "slot": "57", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:98" + "src": "contracts/vault/VaultStorage.sol:101" }, { "label": "autoAllocateThreshold", @@ -103,7 +103,7 @@ "slot": "58", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:100" + "src": "contracts/vault/VaultStorage.sol:103" }, { "label": "rebaseThreshold", @@ -111,15 +111,15 @@ "slot": "59", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:102" + "src": "contracts/vault/VaultStorage.sol:105" }, { "label": "oUSD", "offset": 0, "slot": "60", - "type": "t_contract(OUSD)36965", + "type": "t_contract(OUSD)37977", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:106" + "src": "contracts/vault/VaultStorage.sol:109" }, { "label": "_deprecated_rebaseHooksAddr", @@ -127,7 +127,7 @@ "slot": "61", "type": "t_address", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:113" + "src": "contracts/vault/VaultStorage.sol:116" }, { "label": "_deprecated_uniswapAddr", @@ -135,7 +135,7 @@ "slot": "62", "type": "t_address", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:117" + "src": "contracts/vault/VaultStorage.sol:120" }, { "label": "strategistAddr", @@ -143,7 +143,7 @@ "slot": "63", "type": "t_address", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:120" + "src": "contracts/vault/VaultStorage.sol:123" }, { "label": "assetDefaultStrategies", @@ -151,7 +151,7 @@ "slot": "64", "type": "t_mapping(t_address,t_address)", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:124" + "src": "contracts/vault/VaultStorage.sol:128" }, { "label": "maxSupplyDiff", @@ -159,7 +159,7 @@ "slot": "65", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:127" + "src": "contracts/vault/VaultStorage.sol:132" }, { "label": "trusteeAddress", @@ -167,7 +167,7 @@ "slot": "66", "type": "t_address", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:130" + "src": "contracts/vault/VaultStorage.sol:135" }, { "label": "trusteeFeeBps", @@ -175,7 +175,7 @@ "slot": "67", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:133" + "src": "contracts/vault/VaultStorage.sol:138" }, { "label": "_deprecated_swapTokens", @@ -183,7 +183,7 @@ "slot": "68", "type": "t_array(t_address)dyn_storage", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:136" + "src": "contracts/vault/VaultStorage.sol:141" }, { "label": "ousdMetaStrategy", @@ -191,7 +191,7 @@ "slot": "69", "type": "t_address", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:141" + "src": "contracts/vault/VaultStorage.sol:146" }, { "label": "netOusdMintedForStrategy", @@ -199,7 +199,7 @@ "slot": "70", "type": "t_int256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:144" + "src": "contracts/vault/VaultStorage.sol:149" }, { "label": "netOusdMintForStrategyThreshold", @@ -207,15 +207,31 @@ "slot": "71", "type": "t_uint256", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:147" + "src": "contracts/vault/VaultStorage.sol:152" }, { "label": "swapConfig", "offset": 0, "slot": "72", - "type": "t_struct(SwapConfig)42619_storage", + "type": "t_struct(SwapConfig)43916_storage", "contract": "VaultStorage", - "src": "contracts/vault/VaultStorage.sol:161" + "src": "contracts/vault/VaultStorage.sol:166" + }, + { + "label": "__gap", + "offset": 0, + "slot": "73", + "type": "t_array(t_uint256)50_storage", + "contract": "VaultStorage", + "src": "contracts/vault/VaultStorage.sol:169" + }, + { + "label": "wethAssetIndex", + "offset": 0, + "slot": "123", + "type": "t_uint256", + "contract": "OETHVaultCore", + "src": "contracts/vault/OETHVaultCore.sol:20" } ], "types": { @@ -235,11 +251,11 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(OUSD)36965": { + "t_contract(OUSD)37977": { "label": "contract OUSD", "numberOfBytes": "20" }, - "t_enum(UnitConversion)42488": { + "t_enum(UnitConversion)43785": { "label": "enum VaultStorage.UnitConversion", "members": [ "DECIMALS", @@ -255,15 +271,15 @@ "label": "mapping(address => address)", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Asset)42498_storage)": { + "t_mapping(t_address,t_struct(Asset)43795_storage)": { "label": "mapping(address => struct VaultStorage.Asset)", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Strategy)42513_storage)": { + "t_mapping(t_address,t_struct(Strategy)43810_storage)": { "label": "mapping(address => struct VaultStorage.Strategy)", "numberOfBytes": "32" }, - "t_struct(Asset)42498_storage": { + "t_struct(Asset)43795_storage": { "label": "struct VaultStorage.Asset", "members": [ { @@ -274,7 +290,7 @@ }, { "label": "unitConversion", - "type": "t_enum(UnitConversion)42488", + "type": "t_enum(UnitConversion)43785", "offset": 1, "slot": "0" }, @@ -293,7 +309,7 @@ ], "numberOfBytes": "32" }, - "t_struct(Strategy)42513_storage": { + "t_struct(Strategy)43810_storage": { "label": "struct VaultStorage.Strategy", "members": [ { @@ -311,7 +327,7 @@ ], "numberOfBytes": "64" }, - "t_struct(SwapConfig)42619_storage": { + "t_struct(SwapConfig)43916_storage": { "label": "struct VaultStorage.SwapConfig", "members": [ {