From 6c8b30f9b31b0d89d3dd784c6a55a130847c0f8f Mon Sep 17 00:00:00 2001 From: Franck Date: Wed, 3 Feb 2021 14:50:53 -0800 Subject: [PATCH] Deploy 13 (#545) * Rinkeby deploy * mainnet deploy --- contracts/deploy/013_trustee.js | 2 +- .../deployments/mainnet/.migrations.json | 3 +- contracts/deployments/mainnet/VaultCore.json | 134 ++++++++++++++---- .../deployments/rinkeby/.migrations.json | 3 +- contracts/deployments/rinkeby/VaultCore.json | 134 ++++++++++++++---- .../storageLayout/mainnet/VaultCore.json | 62 ++++---- dapp/network.mainnet.json | 91 ++++++++++-- dapp/network.rinkeby.json | 91 ++++++++++-- 8 files changed, 416 insertions(+), 104 deletions(-) diff --git a/contracts/deploy/013_trustee.js b/contracts/deploy/013_trustee.js index 446c5ab56e..695a65e91a 100644 --- a/contracts/deploy/013_trustee.js +++ b/contracts/deploy/013_trustee.js @@ -14,7 +14,7 @@ const { const { proposeArgs } = require("../utils/governor"); const { getTxOpts } = require("../utils/tx"); -const deployName = "013_upgrades"; +const deployName = "013_trustee"; /** * Deploys the vault trustee feature: diff --git a/contracts/deployments/mainnet/.migrations.json b/contracts/deployments/mainnet/.migrations.json index 241c99bf9a..9cc5f5bc31 100644 --- a/contracts/deployments/mainnet/.migrations.json +++ b/contracts/deployments/mainnet/.migrations.json @@ -9,5 +9,6 @@ "010_upgrade_single_asset_staking": 1609971639, "011_ousd_fix": 1610148010, "005_compensation_claims": 1610487584, - "012_upgrades": 1612303613 + "012_upgrades": 1612303613, + "013_trustee": 1612380836 } \ No newline at end of file diff --git a/contracts/deployments/mainnet/VaultCore.json b/contracts/deployments/mainnet/VaultCore.json index 78aea0bedd..4a0fb3652c 100644 --- a/contracts/deployments/mainnet/VaultCore.json +++ b/contracts/deployments/mainnet/VaultCore.json @@ -1,5 +1,5 @@ { - "address": "0xE54f14FC3fBc5915D070DE4758bcF591541BD1c3", + "address": "0x3e803eEA623eE4793f0f49790A813811da5249f4", "abi": [ { "constant": true, @@ -86,6 +86,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeFeeBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -116,6 +131,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -347,13 +377,7 @@ "constant": false, "inputs": [], "name": "rebase", - "outputs": [ - { - "internalType": "uint256", - "name": "newTotalSupply", - "type": "uint256" - } - ], + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -702,6 +726,57 @@ "name": "MaxSupplyDiffChanged", "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" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_basis", + "type": "uint256" + } + ], + "name": "TrusteeFeeBpsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "TrusteeAddressChanged", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -741,42 +816,42 @@ "type": "event" } ], - "transactionHash": "0xd34a3c38cc175aca484668ee2c60673db41f4816165600aed935d21095591cbd", + "transactionHash": "0x5e6fae5891d060a0f1d907415ec49f5951b536687f90e94b56928a338f27373d", "receipt": { "to": null, "from": "0x71F78361537A6f7B6818e7A760c8bC0146D93f50", - "contractAddress": "0xE54f14FC3fBc5915D070DE4758bcF591541BD1c3", - "transactionIndex": 23, - "gasUsed": "3139150", - "logsBloom": "0x00000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000008000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000020000000000000000000800000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000200000000000000000020000000040000000000000000000000000000000000000200000000000000000000", - "blockHash": "0x437fb7a8f1265ef741f88f6f02bca7569509ec4100de38c6d86c9bac2a2aaf66", - "transactionHash": "0xd34a3c38cc175aca484668ee2c60673db41f4816165600aed935d21095591cbd", + "contractAddress": "0x3e803eEA623eE4793f0f49790A813811da5249f4", + "transactionIndex": 128, + "gasUsed": "3252626", + "logsBloom": "0x00000000000000000002000000000000000000000000001000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000020000000000000000000800000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000200000000000000000020000000000000000000000000000000000000000000000100000000000000000000", + "blockHash": "0x20d7ff5f34c346008f409d50046f36f420a868e7a93375f7645dbd313afe9191", + "transactionHash": "0x5e6fae5891d060a0f1d907415ec49f5951b536687f90e94b56928a338f27373d", "logs": [ { - "transactionIndex": 23, - "blockNumber": 11551806, - "transactionHash": "0xd34a3c38cc175aca484668ee2c60673db41f4816165600aed935d21095591cbd", - "address": "0xE54f14FC3fBc5915D070DE4758bcF591541BD1c3", + "transactionIndex": 128, + "blockNumber": 11785186, + "transactionHash": "0x5e6fae5891d060a0f1d907415ec49f5951b536687f90e94b56928a338f27373d", + "address": "0x3e803eEA623eE4793f0f49790A813811da5249f4", "topics": [ "0xc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000071f78361537a6f7b6818e7a760c8bc0146d93f50" ], "data": "0x", - "logIndex": 48, - "blockHash": "0x437fb7a8f1265ef741f88f6f02bca7569509ec4100de38c6d86c9bac2a2aaf66" + "logIndex": 107, + "blockHash": "0x20d7ff5f34c346008f409d50046f36f420a868e7a93375f7645dbd313afe9191" } ], - "blockNumber": 11551806, - "cumulativeGasUsed": "5041213", + "blockNumber": 11785186, + "cumulativeGasUsed": "8816835", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "d641aaf0ed5d604d73e8f53c6d96978e", - "metadata": "{\"compiler\":{\"version\":\"0.5.11+commit.22be8592.mod\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"redeemFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"uniswapAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaultBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllAssets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getStrategyCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebaseThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebasePaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"strategistAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"claimGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"checkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedeemOutputs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeemAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxSupplyDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"isSupportedAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoAllocateThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAssetCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetDefaultStrategies\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"allocate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rebase\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTotalSupply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"priceProvider\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isGovernor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"transferGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"capitalPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_assets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mintMultiple\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImpl\",\"type\":\"address\"}],\"name\":\"setAdminImpl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"AssetSupported\",\"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\":\"_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\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"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\":[],\"name\":\"CapitalPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebasePaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebaseUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vaultBuffer\",\"type\":\"uint256\"}],\"name\":\"VaultBufferUpdated\",\"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\":\"_priceProvider\",\"type\":\"address\"}],\"name\":\"PriceProviderUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"AllocateThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"RebaseThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"UniswapUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"StrategistUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupplyDiff\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyDiffChanged\",\"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\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"GovernorshipTransferred\",\"type\":\"event\"}],\"devdoc\":{\"methods\":{\"allocate()\":{\"details\":\"Allocate unallocated funds on Vault to strategies.*\"},\"checkBalance(address)\":{\"params\":{\"_asset\":\"Address of asset\"},\"return\":\"uint256 Balance of asset in decimals of asset\"},\"claimGovernance()\":{\"details\":\"Claim Governance of the contract to a new account (`newGovernor`). Can only be called by the new Governor.\"},\"getAllAssets()\":{\"details\":\"Return all asset addresses in order\"},\"getAssetCount()\":{\"details\":\"Return the number of assets suppported by the Vault.\"},\"getStrategyCount()\":{\"details\":\"Return the number of strategies active on the Vault.\"},\"governor()\":{\"details\":\"Returns the address of the current Governor.\"},\"isGovernor()\":{\"details\":\"Returns true if the caller is the current Governor.\"},\"mint(address,uint256,uint256)\":{\"details\":\"Deposit a supported asset and mint OUSD.\",\"params\":{\"_amount\":\"Amount of the asset being deposited\",\"_asset\":\"Address of the asset being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"mintMultiple(address[],uint256[],uint256)\":{\"details\":\"Mint for multiple assets in the same call.\",\"params\":{\"_amounts\":\"Amount of each asset at the same index in the _assets to deposit.\",\"_assets\":\"Addresses of assets being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"rebase()\":{\"details\":\"Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD.\",\"return\":\"uint256 New total supply of OUSD\"},\"redeem(uint256,uint256)\":{\"details\":\"Withdraw a supported asset and burn OUSD.\",\"params\":{\"_amount\":\"Amount of OUSD to burn\",\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"redeemAll(uint256)\":{\"params\":{\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"setAdminImpl(address)\":{\"details\":\"set the implementation for the admin, this needs to be in a base class else we cannot set it\",\"params\":{\"newImpl\":\"address pf the implementation\"}},\"totalValue()\":{\"details\":\"Determine the total value of assets held by the vault and its strategies.\",\"return\":\"uint256 value Total value in USD (1e18)\"},\"transferGovernance(address)\":{\"details\":\"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\",\"params\":{\"_newGovernor\":\"Address of the new Governor\"}}}},\"userdoc\":{\"methods\":{\"allocate()\":{\"notice\":\"Allocate unallocated funds on Vault to strategies.\"},\"calculateRedeemOutputs(uint256)\":{\"notice\":\"Calculate the outputs for a redeem function, i.e. the mix of coins that will be returned\"},\"checkBalance(address)\":{\"notice\":\"Get the balance of an asset held in Vault and all strategies.\"},\"redeemAll(uint256)\":{\"notice\":\"Withdraw a supported asset and burn all OUSD.\"}}}},\"settings\":{\"compilationTarget\":{\"contracts/vault/VaultCore.sol\":\"VaultCore\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x640b6dee7a4b830bdfd52b5031a07fc2b12209f5b2e29e5d364a7d37f69d8076\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\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(address sender, address recipient, uint256 amount) 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\":\"0xe5bb0f57cff3e299f360052ba50f1ea0fff046df2be070b6943e0e3c3fdad8a9\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6f2c9955d65c522b80f4b8792f076512d2df947d2112cbc4d98a4781ed42ede2\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\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 * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1a8e5072509c5ea7365eb1d48030b9be865140c8fb779968da0a459a0e174a11\"},\"@openzeppelin/upgrades/contracts/Initializable.sol\":{\"content\":\"pragma solidity >=0.4.24 <0.7.0;\\n\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\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 use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || isConstructor() || !initialized, \\\"Contract instance has already been initialized\\\");\\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 /// @dev Returns true if and only if the function is running in the constructor\\n function isConstructor() private view returns (bool) {\\n // extcodesize checks the size of the code stored in an address, and\\n // address returns the current address. Since the code is still not\\n // deployed when running a constructor, any checks on its code size will\\n // yield zero, making it an effective way to detect if a contract is\\n // under construction or not.\\n address self = address(this);\\n uint256 cs;\\n assembly { cs := extcodesize(self) }\\n return cs == 0;\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0x9bfec92e36234ecc99b5d37230acb6cd1f99560233753162204104a4897e8721\"},\"contracts/governance/Governable.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Governable Contract\\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\\n private constant governorPosition = 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\\n\\n // keccak256(\\\"OUSD.pending.governor\\\");\\n bytes32\\n private constant pendingGovernorPosition = 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\\n\\n // keccak256(\\\"OUSD.reentry.status\\\");\\n bytes32\\n private constant reentryStatusPosition = 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() internal {\\n _setGovernor(msg.sender);\\n emit GovernorshipTransferred(address(0), _governor());\\n }\\n\\n /**\\n * @dev 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 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 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 * @dev 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 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 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 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 assembly {\\n sstore(position, _NOT_ENTERED)\\n }\\n }\\n\\n function _setPendingGovernor(address newGovernor) internal {\\n bytes32 position = pendingGovernorPosition;\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0x3e51ea48102945bf4b305bf9722a07514a585a29555d92f8c84352d1a4cfcee1\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x01eab42b6d54fa5389598e0663c24680ecc017e2da848e8ea1c40aeaa8225eef\"},\"contracts/interfaces/IMinMaxOracle.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IMinMaxOracle {\\n //Assuming 8 decimals\\n function priceMin(string calldata symbol) external view returns (uint256);\\n\\n function priceMax(string calldata symbol) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x164c8759ca5a8e39bbe1de6b2504098c543b2f15663c9d452e083418f8313f48\"},\"contracts/interfaces/IStrategy.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 Lending 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 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 collectRewardToken() external;\\n\\n /**\\n * @dev The address of the reward token for the Strategy.\\n */\\n function rewardTokenAddress() external pure returns (address);\\n\\n /**\\n * @dev The threshold (denominated in the reward token) over which the\\n * vault will auto harvest on allocate calls.\\n */\\n function rewardLiquidationThreshold() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9ef9546d60635c630e3446f270bc93f34593f5c77db8c671146f6c1eb0b2774\"},\"contracts/interfaces/IVault.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IVault {\\n event AssetSupported(address _asset);\\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 DepositsPaused();\\n event DepositsUnpaused();\\n\\n // Governable.sol\\n function transferGovernance(address _newGovernor) external;\\n\\n function claimGovernance() external;\\n\\n function governor() external view returns (address);\\n\\n // VaultAdmin.sol\\n function setPriceProvider(address _priceProvider) external;\\n\\n function priceProvider() external view returns (address);\\n\\n function setRedeemFeeBps(uint256 _redeemFeeBps) external;\\n\\n function redeemFeeBps() external view returns (uint256);\\n\\n function setVaultBuffer(uint256 _vaultBuffer) external;\\n\\n function vaultBuffer() external view returns (uint256);\\n\\n function setAutoAllocateThreshold(uint256 _threshold) external;\\n\\n function autoAllocateThreshold() external view returns (uint256);\\n\\n function setRebaseThreshold(uint256 _threshold) external;\\n\\n function rebaseThreshold() external view returns (uint256);\\n\\n function setStrategistAddr(address _address) external;\\n\\n function strategistAddr() external view returns (address);\\n\\n function setUniswapAddr(address _address) external;\\n\\n function uniswapAddr() external view returns (address);\\n\\n function supportAsset(address _asset) external;\\n\\n function approveStrategy(address _addr) external;\\n\\n function removeStrategy(address _addr) external;\\n\\n function setAssetDefaultStrategy(address _asset, address _strategy)\\n external;\\n\\n function assetDefaultStrategies(address _asset)\\n external\\n view\\n returns (address);\\n\\n function pauseRebase() external;\\n\\n function unpauseRebase() external;\\n\\n function rebasePaused() external view returns (bool);\\n\\n function pauseCapital() external;\\n\\n function unpauseCapital() external;\\n\\n function capitalPaused() external view returns (bool);\\n\\n function transferToken(address _asset, uint256 _amount) external;\\n\\n function harvest() external;\\n\\n function harvest(address _strategyAddr) external;\\n\\n function priceUSDMint(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n function priceUSDRedeem(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n // VaultCore.sol\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount) external;\\n\\n function redeemAll(uint256 _minimumUnitAmount) external;\\n\\n function allocate() external;\\n\\n function reallocate(\\n address _strategyFromAddress,\\n address _strategyToAddress,\\n address[] calldata _assets,\\n uint256[] calldata _amounts\\n ) external;\\n\\n function rebase() external returns (uint256);\\n\\n function totalValue() external view returns (uint256 value);\\n\\n function checkBalance() external view returns (uint256);\\n\\n function checkBalance(address _asset) external view returns (uint256);\\n\\n function calculateRedeemOutputs(uint256 _amount)\\n external\\n view\\n returns (uint256[] memory);\\n\\n function getAssetCount() external view returns (uint256);\\n\\n function getAllAssets() external view returns (address[] memory);\\n\\n function getStrategyCount() external view returns (uint256);\\n\\n function isSupportedAsset(address _asset) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x2a5958a8d9e0c878b5d62578e03aa9c39a7f1803ff7e308074ada326a9d45518\"},\"contracts/token/OUSD.sol\":{\"content\":\"pragma solidity 0.5.11;\\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/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport {\\n InitializableERC20Detailed\\n} 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 TotalSupplyUpdated(\\n uint256 totalSupply,\\n uint256 rebasingCredits,\\n uint256 rebasingCreditsPerToken\\n );\\n\\n // MAX_SUPPLY is chosen to guarantee applied changes to _totalSupply in\\n // changeSupply(_newTotalSupply) deviate from the value provided in\\n // _newTotalSupply by < 1\\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\\n\\n uint256 public _totalSupply;\\n uint256 public rebasingCredits;\\n // Exchange rate between internal credits and OUSD\\n uint256 public rebasingCreditsPerToken;\\n\\n mapping(address => uint256) private _deprecated_creditBalances;\\n\\n // Allowances denominated in OUSD\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n address public vaultAddress = address(0);\\n\\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 _deprecated_nonRebasingCredits;\\n uint256 public nonRebasingSupply;\\n mapping(address => uint256) public nonRebasingCreditsPerToken;\\n enum RebaseOptions { NotSet, OptOut, OptIn }\\n mapping(address => RebaseOptions) public rebaseState;\\n\\n mapping(address => uint256) private _creditBalances;\\n\\n function initialize(\\n string calldata _nameArg,\\n string calldata _symbolArg,\\n address _vaultAddress\\n ) external onlyGovernor initializer {\\n InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);\\n rebasingCreditsPerToken = 1e18;\\n vaultAddress = _vaultAddress;\\n }\\n\\n /**\\n * @dev Verifies that the caller is the Savings Manager 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 returns (uint256) {\\n return _totalSupply;\\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) public view returns (uint256) {\\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 * @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 return (_creditBalances[_account], _creditsPerToken(_account));\\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) public returns (bool) {\\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 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 an owner has allowed to a _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 returns (uint256)\\n {\\n return _allowances[_owner][_spender];\\n }\\n\\n /**\\n * @dev Approve the passed address to spend the specified _amount of tokens on behalf of\\n * msg.sender. This method is included for ERC20 compatibility.\\n * increaseAllowance and decreaseAllowance should be used instead.\\n * Changing an allowance with this method brings the risk that someone may transfer both\\n * the old and the new allowance - if they are both greater than zero - if a transfer\\n * transaction is mined before the later approve() call is mined.\\n *\\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) public returns (bool) {\\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 a _spender.\\n * This method should be used instead of approve() to avoid the double approval vulnerability\\n * 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 a _spender.\\n * @param _spender The address which will spend the funds.\\n * @param _subtractedValue The _amount of tokens to decrease the allowance 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 return _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 return _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\\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 accounts balance non rebasing, i.e. does not alter with rebases\\n * @param _account Address of the account.\\n */\\n function _isNonRebasingAccount(address _account) internal returns (bool) {\\n if (Address.isContract(_account)) {\\n // Contracts by default opt out\\n if (rebaseState[_account] == RebaseOptions.OptIn) {\\n // If they've opted in explicitly it is not a non rebasing\\n // address\\n return false;\\n }\\n // Is a non rebasing account because no explicit opt in\\n // Make sure the rebasing/non-rebasing supply is updated and\\n // fixed credits per token is set for this account\\n _ensureRebasingMigration(_account);\\n return true;\\n } else {\\n // EOAs by default opt in\\n // Check for explicit opt out\\n return rebaseState[_account] == RebaseOptions.OptOut;\\n }\\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 // 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(_creditBalances[_account]);\\n }\\n }\\n\\n /**\\n * @dev Add a contract address to the non rebasing exception list. I.e. the\\n * address's balance will be part of rebases so the account will be exposed\\n * to upside and downside.\\n */\\n function rebaseOptIn() public nonReentrant {\\n require(_isNonRebasingAccount(msg.sender), \\\"Account has not opted out\\\");\\n\\n // Convert balance into the same amount at the current exchange rate\\n uint256 newCreditBalance = _creditBalances[msg.sender]\\n .mul(rebasingCreditsPerToken)\\n .div(_creditsPerToken(msg.sender));\\n\\n // Decreasing non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.sub(balanceOf(msg.sender));\\n\\n _creditBalances[msg.sender] = newCreditBalance;\\n\\n // Increase rebasing credits, totalSupply remains unchanged so no\\n // adjustment necessary\\n rebasingCredits = rebasingCredits.add(_creditBalances[msg.sender]);\\n\\n rebaseState[msg.sender] = RebaseOptions.OptIn;\\n\\n // Delete any fixed credits per token\\n delete nonRebasingCreditsPerToken[msg.sender];\\n }\\n\\n /**\\n * @dev Remove a contract address to the non rebasing exception list.\\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 }\\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 * @return uint256 representing the new total supply.\\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 TotalSupplyUpdated(\\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 TotalSupplyUpdated(\\n _totalSupply,\\n rebasingCredits,\\n rebasingCreditsPerToken\\n );\\n }\\n}\\n\",\"keccak256\":\"0x18d15a386750d93a6252becc33d8df577a397c0ea44135a7208ce33bb65233c6\"},\"contracts/utils/Helpers.sol\":{\"content\":\"pragma solidity 0.5.11;\\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\":\"0xd2ca92e0af883dc1aec5b22caced274e59829e0e30a9e955dcc48b8d921f5cdc\"},\"contracts/utils/InitializableERC20Detailed.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 */\\ncontract InitializableERC20Detailed is IERC20 {\\n // Ignore these, they are present to align storage slots correctly after\\n // upgrade\\n mapping(address => uint256) private __gap1;\\n mapping(address => mapping(address => uint256)) private __gap2;\\n uint256 private constant __gap3 = 0;\\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 * @dev Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0xdb555620ce66bb4a07890e352683b0e6777fb06585935e5ce3ab80e6282c96ce\"},\"contracts/utils/StableMath.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/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 adjustment Amount to adjust by e.g. scaleBy(1e18, -1) == 1e17\\n */\\n function scaleBy(uint256 x, int8 adjustment)\\n internal\\n pure\\n returns (uint256)\\n {\\n if (adjustment > 0) {\\n x = x.mul(10**uint256(adjustment));\\n } else if (adjustment < 0) {\\n x = x.div(10**uint256(adjustment * -1));\\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 9e38 / 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\":\"0xa77fccf850feb6d54ba3a6530f92554caef8a67a1ceb573d4f8a5d1bf64ff9d2\"},\"contracts/vault/VaultCore.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Vault Contract\\n * @notice The Vault contract stores assets. On a deposit, OUSD will be minted\\n and sent to the depositor. On a withdrawal, OUSD will be burned and\\n assets will be sent to the withdrawer. The Vault accepts deposits of\\n interest form yield bearing strategies which will modify the supply\\n of OUSD.\\n * @author Origin Protocol Inc\\n */\\n\\nimport \\\"./VaultStorage.sol\\\";\\nimport { IMinMaxOracle } from \\\"../interfaces/IMinMaxOracle.sol\\\";\\nimport { IVault } from \\\"../interfaces/IVault.sol\\\";\\n\\ncontract VaultCore is VaultStorage {\\n uint256 constant MAX_UINT = 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 /**\\n * @dev Deposit a supported asset and mint OUSD.\\n * @param _asset Address of the asset being deposited\\n * @param _amount Amount of the asset being deposited\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(assets[_asset].isSupported, \\\"Asset is not supported\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 price = IMinMaxOracle(priceProvider).priceMin(\\n Helpers.getSymbol(_asset)\\n );\\n if (price > 1e8) {\\n price = 1e8;\\n }\\n uint256 assetDecimals = Helpers.getDecimals(_asset);\\n uint256 unitAdjustedDeposit = _amount.scaleBy(int8(18 - assetDecimals));\\n uint256 priceAdjustedDeposit = _amount.mulTruncateScale(\\n price.scaleBy(int8(10)), // 18-8 because oracles have 8 decimals precision\\n 10**assetDecimals\\n );\\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 (unitAdjustedDeposit >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n // Mint matching OUSD\\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 (unitAdjustedDeposit >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Mint for multiple assets in the same call.\\n * @param _assets Addresses of assets being deposited\\n * @param _amounts Amount of each asset at the same index in the _assets\\n * to deposit.\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amounts,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(_assets.length == _amounts.length, \\\"Parameter length mismatch\\\");\\n\\n uint256 unitAdjustedTotal = 0;\\n uint256 priceAdjustedTotal = 0;\\n uint256[] memory assetPrices = _getAssetPrices(false);\\n for (uint256 j = 0; j < _assets.length; j++) {\\n // In memoriam\\n require(assets[_assets[j]].isSupported, \\\"Asset is not supported\\\");\\n require(_amounts[j] > 0, \\\"Amount must be greater than 0\\\");\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (_assets[j] == allAssets[i]) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n uint256 price = assetPrices[i];\\n if (price > 1e18) {\\n price = 1e18;\\n }\\n unitAdjustedTotal = unitAdjustedTotal.add(\\n _amounts[j].scaleBy(int8(18 - assetDecimals))\\n );\\n priceAdjustedTotal = priceAdjustedTotal.add(\\n _amounts[j].mulTruncateScale(price, 10**assetDecimals)\\n );\\n }\\n }\\n }\\n\\n if (_minimumOusdAmount > 0) {\\n require(\\n priceAdjustedTotal >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n }\\n\\n emit Mint(msg.sender, priceAdjustedTotal);\\n\\n // Rebase must happen before any transfers occur.\\n if (unitAdjustedTotal >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n oUSD.mint(msg.sender, priceAdjustedTotal);\\n\\n for (uint256 i = 0; i < _assets.length; i++) {\\n IERC20 asset = IERC20(_assets[i]);\\n asset.safeTransferFrom(msg.sender, address(this), _amounts[i]);\\n }\\n\\n if (unitAdjustedTotal >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n public\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(_amount, _minimumUnitAmount);\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount) internal {\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 _totalSupply = oUSD.totalSupply();\\n uint256 _backingValue = _totalValue();\\n\\n if (maxSupplyDiff > 0) {\\n // Allow a max difference of maxSupplyDiff% between\\n // backing assets value and OUSD total supply\\n uint256 diff = _totalSupply.divPrecisely(_backingValue);\\n\\n require(\\n (diff > 1e18 ? diff.sub(1e18) : uint256(1e18).sub(diff)) <=\\n maxSupplyDiff,\\n \\\"Backing supply liquidity error\\\"\\n );\\n }\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // Calculate redemption outputs\\n uint256[] memory outputs = _calculateRedeemOutputs(_amount);\\n // Send outputs\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (outputs[i] == 0) continue;\\n\\n IERC20 asset = IERC20(allAssets[i]);\\n\\n if (asset.balanceOf(address(this)) >= outputs[i]) {\\n // Use Vault funds first if sufficient\\n asset.safeTransfer(msg.sender, outputs[i]);\\n } else {\\n address strategyAddr = assetDefaultStrategies[allAssets[i]];\\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, allAssets[i], 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 uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n unitTotal = unitTotal.add(\\n outputs[i].scaleBy(int8(18 - assetDecimals))\\n );\\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 if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn all OUSD.\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeemAll(uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n // Unfortunately we have to do balanceOf twice, the rebase may change\\n // the account balance\\n if (oUSD.balanceOf(msg.sender) > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\n * @dev Allocate unallocated funds on Vault to strategies.\\n **/\\n function allocate() public whenNotCapitalPaused nonReentrant {\\n _allocate();\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\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.add(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).sub(vaultBuffer);\\n } else {\\n vaultBufferModifier = vaultBuffer.mul(calculatedTotalValue).div(\\n vaultValue\\n );\\n if (1e18 > vaultBufferModifier) {\\n // E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17\\n // (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault\\n vaultBufferModifier = uint256(1e18).sub(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 the the appropriate\\n // strategy\\n for (uint256 i = 0; i < allAssets.length; 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[address(\\n 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 }\\n }\\n\\n // Harvest for all reward tokens above reward liquidation threshold\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n address rewardTokenAddress = strategy.rewardTokenAddress();\\n if (rewardTokenAddress != address(0)) {\\n uint256 liquidationThreshold = strategy\\n .rewardLiquidationThreshold();\\n if (liquidationThreshold == 0) {\\n // No threshold set, always harvest from strategy\\n IVault(address(this)).harvest(allStrategies[i]);\\n } else {\\n // Check balance against liquidation threshold\\n // Note some strategies don't hold the reward token balance\\n // on their contract so the liquidation threshold should be\\n // set to 0\\n IERC20 rewardToken = IERC20(rewardTokenAddress);\\n uint256 rewardTokenAmount = rewardToken.balanceOf(\\n allStrategies[i]\\n );\\n if (rewardTokenAmount >= liquidationThreshold) {\\n IVault(address(this)).harvest(allStrategies[i]);\\n }\\n }\\n }\\n }\\n }\\n\\n /**\\n * @dev Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OUSD.\\n * @return uint256 New total supply of OUSD\\n */\\n function rebase()\\n public\\n whenNotRebasePaused\\n nonReentrant\\n returns (uint256 newTotalSupply)\\n {\\n return _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 OUSD.\\n * @return uint256 New total supply of OUSD\\n */\\n function _rebase()\\n internal\\n whenNotRebasePaused\\n returns (uint256 newTotalSupply)\\n {\\n if (oUSD.totalSupply() == 0) return 0;\\n uint256 oldTotalSupply = oUSD.totalSupply();\\n newTotalSupply = _totalValue();\\n // Only rachet upwards\\n if (newTotalSupply > oldTotalSupply) {\\n oUSD.changeSupply(newTotalSupply);\\n }\\n }\\n\\n /**\\n * @dev Determine the total value of assets held by the vault and its\\n * strategies.\\n * @return uint256 value Total value in USD (1e18)\\n */\\n function totalValue() external view 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 uint256 value Total value in USD (1e18)\\n */\\n function _totalValue() internal view returns (uint256 value) {\\n return _totalValueInVault().add(_totalValueInStrategies());\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Vault.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInVault() internal view returns (uint256 value) {\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n IERC20 asset = IERC20(allAssets[y]);\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n uint256 balance = asset.balanceOf(address(this));\\n if (balance > 0) {\\n value = value.add(balance.scaleBy(int8(18 - assetDecimals)));\\n }\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Strategies.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategies() internal view returns (uint256 value) {\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n value = value.add(_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 uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategy(address _strategyAddr)\\n internal\\n view\\n returns (uint256 value)\\n {\\n IStrategy strategy = IStrategy(_strategyAddr);\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n if (strategy.supportsAsset(allAssets[y])) {\\n uint256 balance = strategy.checkBalance(allAssets[y]);\\n if (balance > 0) {\\n value = value.add(\\n balance.scaleBy(int8(18 - assetDecimals))\\n );\\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 uint256 Balance of asset in decimals of asset\\n */\\n function _checkBalance(address _asset)\\n internal\\n view\\n returns (uint256 balance)\\n {\\n IERC20 asset = IERC20(_asset);\\n balance = asset.balanceOf(address(this));\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n if (strategy.supportsAsset(_asset)) {\\n balance = balance.add(strategy.checkBalance(_asset));\\n }\\n }\\n }\\n\\n /**\\n * @notice Get the balance of all assets held in Vault and all strategies.\\n * @return uint256 Balance of all assets (1e18)\\n */\\n function _checkBalance() internal view returns (uint256 balance) {\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n balance = balance.add(\\n _checkBalance(allAssets[i]).scaleBy(int8(18 - assetDecimals))\\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 * @notice Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned.\\n * @return 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 = getAssetCount();\\n uint256[] memory assetPrices = _getAssetPrices(true);\\n uint256[] memory assetBalances = new uint256[](assetCount);\\n uint256[] memory assetDecimals = new uint256[](assetCount);\\n uint256 totalBalance = 0;\\n uint256 totalOutputRatio = 0;\\n outputs = new uint256[](assetCount);\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mul(redeemFeeBps).div(10000);\\n _amount = _amount.sub(redeemFee);\\n }\\n\\n // Calculate assets balances and decimals once,\\n // for a large gas savings.\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 balance = _checkBalance(allAssets[i]);\\n uint256 decimals = Helpers.getDecimals(allAssets[i]);\\n assetBalances[i] = balance;\\n assetDecimals[i] = decimals;\\n totalBalance = totalBalance.add(\\n balance.scaleBy(int8(18 - decimals))\\n );\\n }\\n // Calculate totalOutputRatio\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 price = assetPrices[i];\\n // Never give out more than one\\n // stablecoin per dollar of OUSD\\n if (price < 1e18) {\\n price = 1e18;\\n }\\n uint256 ratio = assetBalances[i]\\n .scaleBy(int8(18 - assetDecimals[i]))\\n .mul(price)\\n .div(totalBalance);\\n totalOutputRatio = totalOutputRatio.add(ratio);\\n }\\n // Calculate final outputs\\n uint256 factor = _amount.divPrecisely(totalOutputRatio);\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n outputs[i] = assetBalances[i].mul(factor).div(totalBalance);\\n }\\n }\\n\\n /**\\n * @notice Get an array of the supported asset prices in USD.\\n * @return uint256[] Array of asset prices in USD (1e18)\\n */\\n function _getAssetPrices(bool useMax)\\n internal\\n view\\n returns (uint256[] memory assetPrices)\\n {\\n assetPrices = new uint256[](getAssetCount());\\n\\n IMinMaxOracle oracle = IMinMaxOracle(priceProvider);\\n // Price from Oracle is returned with 8 decimals\\n // _amount is in assetDecimals\\n\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n string memory symbol = Helpers.getSymbol(allAssets[i]);\\n // Get all the USD prices of the asset in 1e18\\n if (useMax) {\\n assetPrices[i] = oracle.priceMax(symbol).scaleBy(int8(18 - 8));\\n } else {\\n assetPrices[i] = oracle.priceMin(symbol).scaleBy(int8(18 - 8));\\n }\\n }\\n }\\n\\n /***************************************\\n Utils\\n ****************************************/\\n\\n /**\\n * @dev Return the number of assets suppported by the Vault.\\n */\\n function getAssetCount() public view returns (uint256) {\\n return allAssets.length;\\n }\\n\\n /**\\n * @dev Return all asset addresses in order\\n */\\n function getAllAssets() external view returns (address[] memory) {\\n return allAssets;\\n }\\n\\n /**\\n * @dev Return the number of strategies active on the Vault.\\n */\\n function getStrategyCount() external view returns (uint256) {\\n return allStrategies.length;\\n }\\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 function() external payable {\\n bytes32 slot = adminImplPosition;\\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(gas, sload(slot), 0, calldatasize, 0, 0)\\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\",\"keccak256\":\"0xb16df039956cf5aa13886f52ff6db1264a77726d81268e9165eb8a31f7f65d7b\"},\"contracts/vault/VaultStorage.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD 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/SafeERC20.sol\\\";\\nimport { SafeMath } from \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.sol\\\";\\n\\nimport { IStrategy } from \\\"../interfaces/IStrategy.sol\\\";\\nimport { Governable } from \\\"../governance/Governable.sol\\\";\\nimport { OUSD } from \\\"../token/OUSD.sol\\\";\\nimport \\\"../utils/Helpers.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\n\\ncontract VaultStorage is Initializable, Governable {\\n using SafeMath for uint256;\\n using StableMath for uint256;\\n using SafeMath for int256;\\n using SafeERC20 for IERC20;\\n\\n event AssetSupported(address _asset);\\n event AssetDefaultStrategyUpdated(address _asset, address _strategy);\\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 RedeemFeeUpdated(uint256 _redeemFeeBps);\\n event PriceProviderUpdated(address _priceProvider);\\n event AllocateThresholdUpdated(uint256 _threshold);\\n event RebaseThresholdUpdated(uint256 _threshold);\\n event UniswapUpdated(address _address);\\n event StrategistUpdated(address _address);\\n event MaxSupplyDiffChanged(uint256 maxSupplyDiff);\\n\\n // Assets supported by the Vault, i.e. Stablecoins\\n struct Asset {\\n bool isSupported;\\n }\\n mapping(address => Asset) assets;\\n address[] allAssets;\\n\\n // Strategies approved for use by the Vault\\n struct Strategy {\\n bool isSupported;\\n uint256 _deprecated; // Deprecated storage slot\\n }\\n mapping(address => Strategy) strategies;\\n address[] allStrategies;\\n\\n // Address of the Oracle price provider contract\\n address public priceProvider;\\n // Pausing bools\\n bool public rebasePaused = false;\\n bool public capitalPaused = true;\\n // Redemption fee in basis points\\n uint256 public redeemFeeBps;\\n // Buffer of assets to keep in Vault to handle (most) withdrawals\\n uint256 public vaultBuffer;\\n // Mints over this amount automatically allocate funds. 18 decimals.\\n uint256 public autoAllocateThreshold;\\n // Mints over this amount automatically rebase. 18 decimals.\\n uint256 public rebaseThreshold;\\n\\n OUSD oUSD;\\n\\n //keccak256(\\\"OUSD.vault.governor.admin.impl\\\");\\n bytes32 constant adminImplPosition = 0xa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9;\\n\\n // Address of the contract responsible for post rebase syncs with AMMs\\n address private _deprecated_rebaseHooksAddr = address(0);\\n\\n // Address of Uniswap\\n address public uniswapAddr = address(0);\\n\\n // Address of the Strategist\\n address public strategistAddr = address(0);\\n\\n // Mapping of asset address to the Strategy that they should automatically\\n // be allocated to\\n mapping(address => address) public assetDefaultStrategies;\\n\\n uint256 public maxSupplyDiff;\\n\\n /**\\n * @dev set the implementation for the admin, this needs to be in a base class else we cannot set it\\n * @param newImpl address pf the implementation\\n */\\n function setAdminImpl(address newImpl) external onlyGovernor {\\n bytes32 position = adminImplPosition;\\n assembly {\\n sstore(position, newImpl)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2e47ddd6070edf156bfe8be58f3f8fc677935f81ee5076c1b95444eed05eac33\"}},\"version\":1}", - "bytecode": "0x60806040526037805461ffff60a01b19167501000000000000000000000000000000000000000000179055603d80546001600160a01b0319908116909155603e805482169055603f8054909116905562000062336001600160e01b03620000bb16565b620000756001600160e01b03620000ce16565b6001600160a01b031660006001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3620000e2565b600080516020620037da83398151915255565b600080516020620037da8339815191525490565b6136e880620000f26000396000f3fe6080604052600436106101c25760003560e01c80637cbc2373116100f7578063af14052c11610095578063d4c3eea011610064578063d4c3eea014610590578063e6cc5432146105a5578063f0efb4c7146105ba578063fc0cfeee14610689576101c2565b8063af14052c1461051e578063b888879e14610533578063c7af335214610548578063d38bfff41461055d576101c2565b80639fa1826e116100d15780639fa1826e146104ac578063a0aead4d146104c1578063a403e4d5146104d6578063abaa991614610509576101c2565b80637cbc2373146104345780638e510b52146104645780639be918e614610479576101c2565b806352d38e5d116101645780635d36b1901161013e5780635d36b190146103985780635f515226146103ad57806367bd7ba3146103e05780637136a7a61461040a576101c2565b806352d38e5d1461034557806353ca9f241461035a578063570d8e1d14610383576101c2565b8063156e29f6116101a0578063156e29f6146102755780631edfe3da146102b65780632acada4d146102cb57806331e19cfa14610330576101c2565b806309f6442c146102085780630c340a241461022f578063128a8b0514610260575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610203573d6000f35b3d6000fd5b34801561021457600080fd5b5061021d6106bc565b60408051918252519081900360200190f35b34801561023b57600080fd5b506102446106c2565b604080516001600160a01b039092168252519081900360200190f35b34801561026c57600080fd5b506102446106d2565b34801561028157600080fd5b506102b46004803603606081101561029857600080fd5b506001600160a01b0381351690602081013590604001356106e1565b005b3480156102c257600080fd5b5061021d610af6565b3480156102d757600080fd5b506102e0610afc565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561031c578181015183820152602001610304565b505050509050019250505060405180910390f35b34801561033c57600080fd5b5061021d610b5e565b34801561035157600080fd5b5061021d610b64565b34801561036657600080fd5b5061036f610b6a565b604080519115158252519081900360200190f35b34801561038f57600080fd5b50610244610b7a565b3480156103a457600080fd5b506102b4610b89565b3480156103b957600080fd5b5061021d600480360360208110156103d057600080fd5b50356001600160a01b0316610beb565b3480156103ec57600080fd5b506102e06004803603602081101561040357600080fd5b5035610bfc565b34801561041657600080fd5b506102b46004803603602081101561042d57600080fd5b5035610c07565b34801561044057600080fd5b506102b46004803603604081101561045757600080fd5b5080359060200135610dd9565b34801561047057600080fd5b5061021d610ec2565b34801561048557600080fd5b5061036f6004803603602081101561049c57600080fd5b50356001600160a01b0316610ec8565b3480156104b857600080fd5b5061021d610ee6565b3480156104cd57600080fd5b5061021d610eec565b3480156104e257600080fd5b50610244600480360360208110156104f957600080fd5b50356001600160a01b0316610ef2565b34801561051557600080fd5b506102b4610f0d565b34801561052a57600080fd5b5061021d610fc8565b34801561053f57600080fd5b5061024461108a565b34801561055457600080fd5b5061036f611099565b34801561056957600080fd5b506102b46004803603602081101561058057600080fd5b50356001600160a01b03166110bc565b34801561059c57600080fd5b5061021d611168565b3480156105b157600080fd5b5061036f611172565b3480156105c657600080fd5b506102b4600480360360608110156105dd57600080fd5b8101906020810181356401000000008111156105f857600080fd5b82018360208201111561060a57600080fd5b8035906020019184602083028401116401000000008311171561062c57600080fd5b91939092909160208101903564010000000081111561064a57600080fd5b82018360208201111561065c57600080fd5b8035906020019184602083028401116401000000008311171561067e57600080fd5b919350915035611182565b34801561069557600080fd5b506102b4600480360360208110156106ac57600080fd5b50356001600160a01b031661167f565b60385481565b60006106cc6116fc565b90505b90565b603e546001600160a01b031681565b603754600160a81b900460ff1615610731576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610789576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff166107f3576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610848576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf061086588611721565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108b1578181015183820152602001610899565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156108fb57600080fd5b505afa15801561090f573d6000803e3d6000fd5b505050506040513d602081101561092557600080fd5b505190506305f5e10081111561093c57506305f5e1005b600061094787611852565b9050600061095f87601284900363ffffffff61190c16565b9050600061098961097785600a63ffffffff61190c16565b8990600a86900a63ffffffff61196616565b905086156109e657868110156109e6576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a3d5750603754600160a01b900460ff16155b15610a4c57610a4a611994565b505b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610a9f57600080fd5b505af1158015610ab3573d6000803e3d6000fd5b508b9250610ad59150506001600160a01b03821633308c63ffffffff611b5d16565b603a548310610ae657610ae6611bbd565b5050505050600182555050505050565b60395481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b5457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b36575b5050505050905090565b60365490565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610b916120ec565b6001600160a01b0316336001600160a01b031614610be05760405162461bcd60e51b81526004018080602001828103825260308152602001806136846030913960400191505060405180910390fd5b610be933612111565b565b6000610bf6826121bf565b92915050565b6060610bf682612380565b603754600160a81b900460ff1615610c57576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610caf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d0157600080fd5b505afa158015610d15573d6000803e3d6000fd5b505050506040513d6020811015610d2b57600080fd5b5051118015610d445750603754600160a01b900460ff16155b15610d5357610d51611994565b505b603c54604080516370a0823160e01b81523360048201529051610dd1926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610d9f57600080fd5b505afa158015610db3573d6000803e3d6000fd5b505050506040513d6020811015610dc957600080fd5b505184612641565b506001905550565b603754600160a81b900460ff1615610e29576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610e81576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ea05750603754600160a01b900460ff16155b15610eaf57610ead611994565b505b610eb98484612641565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610f5d576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610fb5576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255610fc1611bbd565b5060019055565b603754600090600160a01b900460ff161561101c576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415611074576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255611080611994565b9250506001905590565b6037546001600160a01b031681565b60006110a36116fc565b6001600160a01b0316336001600160a01b031614905090565b6110c4611099565b611115576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61111e81612bf3565b806001600160a01b03166111306116fc565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006106cc612c17565b603754600160a81b900460ff1681565b603754600160a81b900460ff16156111d2576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f08339815191528054600281141561122a576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255858414611282576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b600080606061129082612c38565b905060005b898110156114c957603360008c8c848181106112ad57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661131d576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061132b57fe5b9050602002013511611384576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b6034548110156114c0576034818154811061139e57fe5b6000918252602090912001546001600160a01b03168c8c848181106113bf57fe5b905060200201356001600160a01b03166001600160a01b031614156114b857600061140a603483815481106113f057fe5b6000918252602090912001546001600160a01b0316611852565b9050600084838151811061141a57fe5b60200260200101519050670de0b6b3a764000081111561143f5750670de0b6b3a76400005b61147761146a836012038e8e8881811061145557fe5b9050602002013561190c90919063ffffffff16565b889063ffffffff612e3e16565b96506114b36114a68284600a0a8f8f8981811061149057fe5b905060200201356119669092919063ffffffff16565b879063ffffffff612e3e16565b955050505b600101611387565b50600101611295565b5085156115255785821015611525576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b54831015801561157c5750603754600160a01b900460ff16155b1561158b57611589611994565b505b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b1580156115de57600080fd5b505af11580156115f2573d6000803e3d6000fd5b506000925050505b8981101561165d5760008b8b8381811061161057fe5b905060200201356001600160a01b0316905061165433308c8c8681811061163357fe5b90506020020135846001600160a01b0316611b5d909392919063ffffffff16565b506001016115fa565b50603a54831061166f5761166f611bbd565b5050506001825550505050505050565b611687611099565b6116d8576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561179a57600080fd5b81019080805160405193929190846401000000008211156117ba57600080fd5b9083019060208201858111156117cf57600080fd5b82516401000000008111828201881017156117e957600080fd5b82525081516020918201929091019080838360005b838110156118165781810151838201526020016117fe565b50505050905090810190601f1680156118435780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561188e57600080fd5b505afa1580156118a2573d6000803e3d6000fd5b505050506040513d60208110156118b857600080fd5b505160ff169050600481108015906118d1575060128111155b610bf65760405162461bcd60e51b81526004018080602001828103825260298152602001806136106029913960400191505060405180910390fd5b6000808260000b13156119375761193083600084900b600a0a63ffffffff612e9f16565b925061195f565b60008260000b121561195f5761195c836000848103900b600a0a63ffffffff612ef816565b92505b5090919050565b600080611979858563ffffffff612e9f16565b905061198b818463ffffffff612ef816565b95945050505050565b603754600090600160a01b900460ff16156119e8576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3657600080fd5b505afa158015611a4a573d6000803e3d6000fd5b505050506040513d6020811015611a6057600080fd5b5051611a6e575060006106cf565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611ab357600080fd5b505afa158015611ac7573d6000803e3d6000fd5b505050506040513d6020811015611add57600080fd5b50519050611ae9612c17565b915080821115611b5957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611b4057600080fd5b505af1158015611b54573d6000803e3d6000fd5b505050505b5090565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bb7908590612f3a565b50505050565b6000611bc76130f2565b905080611bd45750610be9565b6000611bde6131de565b90506000611bf2838363ffffffff612e3e16565b9050600082611c1e57603954611c1790670de0b6b3a76400009063ffffffff61323016565b9050611c76565b611c4384611c3784603954612e9f90919063ffffffff16565b9063ffffffff612ef816565b905080670de0b6b3a76400001115611c6d57611c17670de0b6b3a76400008263ffffffff61323016565b50505050610be9565b80611c845750505050610be9565b60005b603454811015611e1357600060348281548110611ca057fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611cf357600080fd5b505afa158015611d07573d6000803e3d6000fd5b505050506040513d6020811015611d1d57600080fd5b5051905080611d2d575050611e0b565b6000611d3f828663ffffffff61327216565b6001600160a01b03808516600090815260406020819052902054919250168015801590611d6c5750600082115b15611e065780611d8c6001600160a01b038616828563ffffffff61328716565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b50505050505b505050505b600101611c87565b5060005b6036548110156120e557600060368281548110611e3057fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b158015611e7d57600080fd5b505afa158015611e91573d6000803e3d6000fd5b505050506040513d6020811015611ea757600080fd5b505190506001600160a01b038116156120db576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d6020811015611f1f57600080fd5b5051905080611fae57306001600160a01b0316630e5c011e60368681548110611f4457fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b158015611f9157600080fd5b505af1158015611fa5573d6000803e3d6000fd5b505050506120d9565b60008290506000816001600160a01b03166370a0823160368881548110611fd157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561201f57600080fd5b505afa158015612033573d6000803e3d6000fd5b505050506040513d602081101561204957600080fd5b505190508281106120d657306001600160a01b0316630e5c011e6036888154811061207057fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b1580156120bd57600080fd5b505af11580156120d1573d6000803e3d6000fd5b505050505b50505b505b5050600101611e17565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b03811661216c576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661217e6116fc565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36121bc816132de565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561220a57600080fd5b505afa15801561221e573d6000803e3d6000fd5b505050506040513d602081101561223457600080fd5b5051915060005b6036548110156123795760006036828154811061225457fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b1580156122aa57600080fd5b505afa1580156122be573d6000803e3d6000fd5b505050506040513d60208110156122d457600080fd5b5051156123705761236d816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561233457600080fd5b505afa158015612348573d6000803e3d6000fd5b505050506040513d602081101561235e57600080fd5b5051859063ffffffff612e3e16565b93505b5060010161223b565b5050919050565b6060600061238c610eec565b9050606061239a6001612c38565b90506060826040519080825280602002602001820160405280156123c8578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156123f7578160200160208202803883390190505b506040805186815260208088028201019091529091506000908190868015612429578160200160208202803883390190505b5060385490975015612468576000612452612710611c376038548c612e9f90919063ffffffff16565b9050612464898263ffffffff61323016565b9850505b60005b6034548110156125185760006124a16034838154811061248757fe5b6000918252602090912001546001600160a01b03166121bf565b905060006124b5603484815481106113f057fe5b9050818784815181106124c457fe5b602002602001018181525050808684815181106124dd57fe5b602090810291909101015261250c6124ff83601284900363ffffffff61190c16565b869063ffffffff612e3e16565b9450505060010161246b565b5060005b6034548110156125c957600086828151811061253457fe5b60200260200101519050670de0b6b3a76400008110156125595750670de0b6b3a76400005b60006125ab85611c378461259f8a888151811061257257fe5b60200260200101516012038c898151811061258957fe5b602002602001015161190c90919063ffffffff16565b9063ffffffff612e9f16565b90506125bd848263ffffffff612e3e16565b9350505060010161251c565b5060006125dc898363ffffffff61330216565b905060005b6034548110156126345761261584611c37848985815181106125ff57fe5b6020026020010151612e9f90919063ffffffff16565b89828151811061262157fe5b60209081029190910101526001016125e1565b5050505050505050919050565b60008211612696576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156126db57600080fd5b505afa1580156126ef573d6000803e3d6000fd5b505050506040513d602081101561270557600080fd5b505190506000612713612c17565b604154909150156127ce576000612730838363ffffffff61330216565b9050604154670de0b6b3a764000082116127615761275c670de0b6b3a76400008363ffffffff61323016565b612779565b61277982670de0b6b3a764000063ffffffff61323016565b11156127cc576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a1606061281485612380565b905060005b603454811015612aaa5781818151811061282f57fe5b60200260200101516000141561284457612aa2565b60006034828154811061285357fe5b60009182526020909120015483516001600160a01b03909116915083908390811061287a57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128d857600080fd5b505afa1580156128ec573d6000803e3d6000fd5b505050506040513d602081101561290257600080fd5b50511061293f5761293a3384848151811061291957fe5b6020026020010151836001600160a01b03166132879092919063ffffffff16565b612aa0565b6000604060006034858154811061295257fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612a5f576000819050806001600160a01b031663d9caed1233603487815481106129a757fe5b9060005260206000200160009054906101000a90046001600160a01b03168888815181106129d157fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612a4157600080fd5b505af1158015612a55573d6000803e3d6000fd5b5050505050612a9e565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b600101612819565b508315612b58576000805b8251811015612b00576000612ad0603483815481106113f057fe5b9050612af5612ae88260120386858151811061258957fe5b849063ffffffff612e3e16565b925050600101612ab5565b5084811015612b56576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612bab57600080fd5b505af1158015612bbf573d6000803e3d6000fd5b50505050603b5485118015612bde5750603754600160a01b900460ff16155b156120e557612beb611994565b505050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b60006106cc612c246131de565b612c2c6130f2565b9063ffffffff612e3e16565b6060612c42610eec565b604051908082528060200260200182016040528015612c6b578160200160208202803883390190505b506037549091506001600160a01b031660005b603454811015612379576060612cb460348381548110612c9a57fe5b6000918252602090912001546001600160a01b0316611721565b90508415612dbc57612d9f600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d1d578181015183820152602001612d05565b50505050905090810190601f168015612d4a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612d6757600080fd5b505afa158015612d7b573d6000803e3d6000fd5b505050506040513d6020811015612d9157600080fd5b50519063ffffffff61190c16565b848381518110612dab57fe5b602002602001018181525050612e35565b60405163019af6bf60e41b8152602060048201818152835160248401528351612e1c93600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612d1d578181015183820152602001612d05565b848381518110612e2857fe5b6020026020010181815250505b50600101612c7e565b600082820183811015612e98576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082612eae57506000610bf6565b82820282848281612ebb57fe5b0414612e985760405162461bcd60e51b81526004018080602001828103825260218152602001806136396021913960400191505060405180910390fd5b6000612e9883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613337565b612f4c826001600160a01b03166133d9565b612f9d576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612fdb5780518252601f199092019160209182019101612fbc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461303d576040519150601f19603f3d011682016040523d82523d6000602084013e613042565b606091505b509150915081613099576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611bb7578080602001905160208110156130b557600080fd5b5051611bb75760405162461bcd60e51b815260040180806020018281038252602a81526020018061365a602a913960400191505060405180910390fd5b6000805b603454811015611b595760006034828154811061310f57fe5b6000918252602082200154603480546001600160a01b03909216935061313991859081106113f057fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d60208110156131af57600080fd5b5051905080156131d3576131d06124ff82601285900363ffffffff61190c16565b94505b5050506001016130f6565b6000805b603654811015611b5957613226613219603683815481106131ff57fe5b6000918252602090912001546001600160a01b0316613412565b839063ffffffff612e3e16565b91506001016131e2565b6000612e9883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613595565b6000612e988383670de0b6b3a7640000611966565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526132d9908490612f3a565b505050565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061331d84670de0b6b3a764000063ffffffff612e9f16565b905061332f818463ffffffff612ef816565b949350505050565b600081836133c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613388578181015183820152602001613370565b50505050905090810190601f1680156133b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816133cf57fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061332f575050151592915050565b600081815b603454811015612379576000613433603483815481106113f057fe5b9050826001600160a01b031663aa388af66034848154811061345157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561349f57600080fd5b505afa1580156134b3573d6000803e3d6000fd5b505050506040513d60208110156134c957600080fd5b50511561358c576000836001600160a01b0316635f515226603485815481106134ee57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561353c57600080fd5b505afa158015613550573d6000803e3d6000fd5b505050506040513d602081101561356657600080fd5b50519050801561358a576135876124ff82601285900363ffffffff61190c16565b94505b505b50600101613417565b600081848411156135e75760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613388578181015183820152602001613370565b50505090039056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a72315820ab97d4c53e4ef80d280841f43291bad1192e147995980878462b60004ce5f35164736f6c634300050b00327bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a", - "deployedBytecode": "0x6080604052600436106101c25760003560e01c80637cbc2373116100f7578063af14052c11610095578063d4c3eea011610064578063d4c3eea014610590578063e6cc5432146105a5578063f0efb4c7146105ba578063fc0cfeee14610689576101c2565b8063af14052c1461051e578063b888879e14610533578063c7af335214610548578063d38bfff41461055d576101c2565b80639fa1826e116100d15780639fa1826e146104ac578063a0aead4d146104c1578063a403e4d5146104d6578063abaa991614610509576101c2565b80637cbc2373146104345780638e510b52146104645780639be918e614610479576101c2565b806352d38e5d116101645780635d36b1901161013e5780635d36b190146103985780635f515226146103ad57806367bd7ba3146103e05780637136a7a61461040a576101c2565b806352d38e5d1461034557806353ca9f241461035a578063570d8e1d14610383576101c2565b8063156e29f6116101a0578063156e29f6146102755780631edfe3da146102b65780632acada4d146102cb57806331e19cfa14610330576101c2565b806309f6442c146102085780630c340a241461022f578063128a8b0514610260575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610203573d6000f35b3d6000fd5b34801561021457600080fd5b5061021d6106bc565b60408051918252519081900360200190f35b34801561023b57600080fd5b506102446106c2565b604080516001600160a01b039092168252519081900360200190f35b34801561026c57600080fd5b506102446106d2565b34801561028157600080fd5b506102b46004803603606081101561029857600080fd5b506001600160a01b0381351690602081013590604001356106e1565b005b3480156102c257600080fd5b5061021d610af6565b3480156102d757600080fd5b506102e0610afc565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561031c578181015183820152602001610304565b505050509050019250505060405180910390f35b34801561033c57600080fd5b5061021d610b5e565b34801561035157600080fd5b5061021d610b64565b34801561036657600080fd5b5061036f610b6a565b604080519115158252519081900360200190f35b34801561038f57600080fd5b50610244610b7a565b3480156103a457600080fd5b506102b4610b89565b3480156103b957600080fd5b5061021d600480360360208110156103d057600080fd5b50356001600160a01b0316610beb565b3480156103ec57600080fd5b506102e06004803603602081101561040357600080fd5b5035610bfc565b34801561041657600080fd5b506102b46004803603602081101561042d57600080fd5b5035610c07565b34801561044057600080fd5b506102b46004803603604081101561045757600080fd5b5080359060200135610dd9565b34801561047057600080fd5b5061021d610ec2565b34801561048557600080fd5b5061036f6004803603602081101561049c57600080fd5b50356001600160a01b0316610ec8565b3480156104b857600080fd5b5061021d610ee6565b3480156104cd57600080fd5b5061021d610eec565b3480156104e257600080fd5b50610244600480360360208110156104f957600080fd5b50356001600160a01b0316610ef2565b34801561051557600080fd5b506102b4610f0d565b34801561052a57600080fd5b5061021d610fc8565b34801561053f57600080fd5b5061024461108a565b34801561055457600080fd5b5061036f611099565b34801561056957600080fd5b506102b46004803603602081101561058057600080fd5b50356001600160a01b03166110bc565b34801561059c57600080fd5b5061021d611168565b3480156105b157600080fd5b5061036f611172565b3480156105c657600080fd5b506102b4600480360360608110156105dd57600080fd5b8101906020810181356401000000008111156105f857600080fd5b82018360208201111561060a57600080fd5b8035906020019184602083028401116401000000008311171561062c57600080fd5b91939092909160208101903564010000000081111561064a57600080fd5b82018360208201111561065c57600080fd5b8035906020019184602083028401116401000000008311171561067e57600080fd5b919350915035611182565b34801561069557600080fd5b506102b4600480360360208110156106ac57600080fd5b50356001600160a01b031661167f565b60385481565b60006106cc6116fc565b90505b90565b603e546001600160a01b031681565b603754600160a81b900460ff1615610731576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610789576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff166107f3576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610848576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf061086588611721565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108b1578181015183820152602001610899565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156108fb57600080fd5b505afa15801561090f573d6000803e3d6000fd5b505050506040513d602081101561092557600080fd5b505190506305f5e10081111561093c57506305f5e1005b600061094787611852565b9050600061095f87601284900363ffffffff61190c16565b9050600061098961097785600a63ffffffff61190c16565b8990600a86900a63ffffffff61196616565b905086156109e657868110156109e6576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a3d5750603754600160a01b900460ff16155b15610a4c57610a4a611994565b505b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610a9f57600080fd5b505af1158015610ab3573d6000803e3d6000fd5b508b9250610ad59150506001600160a01b03821633308c63ffffffff611b5d16565b603a548310610ae657610ae6611bbd565b5050505050600182555050505050565b60395481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b5457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b36575b5050505050905090565b60365490565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610b916120ec565b6001600160a01b0316336001600160a01b031614610be05760405162461bcd60e51b81526004018080602001828103825260308152602001806136846030913960400191505060405180910390fd5b610be933612111565b565b6000610bf6826121bf565b92915050565b6060610bf682612380565b603754600160a81b900460ff1615610c57576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610caf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d0157600080fd5b505afa158015610d15573d6000803e3d6000fd5b505050506040513d6020811015610d2b57600080fd5b5051118015610d445750603754600160a01b900460ff16155b15610d5357610d51611994565b505b603c54604080516370a0823160e01b81523360048201529051610dd1926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610d9f57600080fd5b505afa158015610db3573d6000803e3d6000fd5b505050506040513d6020811015610dc957600080fd5b505184612641565b506001905550565b603754600160a81b900460ff1615610e29576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610e81576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ea05750603754600160a01b900460ff16155b15610eaf57610ead611994565b505b610eb98484612641565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610f5d576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610fb5576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255610fc1611bbd565b5060019055565b603754600090600160a01b900460ff161561101c576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415611074576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255611080611994565b9250506001905590565b6037546001600160a01b031681565b60006110a36116fc565b6001600160a01b0316336001600160a01b031614905090565b6110c4611099565b611115576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61111e81612bf3565b806001600160a01b03166111306116fc565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006106cc612c17565b603754600160a81b900460ff1681565b603754600160a81b900460ff16156111d2576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f08339815191528054600281141561122a576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255858414611282576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b600080606061129082612c38565b905060005b898110156114c957603360008c8c848181106112ad57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661131d576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061132b57fe5b9050602002013511611384576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b6034548110156114c0576034818154811061139e57fe5b6000918252602090912001546001600160a01b03168c8c848181106113bf57fe5b905060200201356001600160a01b03166001600160a01b031614156114b857600061140a603483815481106113f057fe5b6000918252602090912001546001600160a01b0316611852565b9050600084838151811061141a57fe5b60200260200101519050670de0b6b3a764000081111561143f5750670de0b6b3a76400005b61147761146a836012038e8e8881811061145557fe5b9050602002013561190c90919063ffffffff16565b889063ffffffff612e3e16565b96506114b36114a68284600a0a8f8f8981811061149057fe5b905060200201356119669092919063ffffffff16565b879063ffffffff612e3e16565b955050505b600101611387565b50600101611295565b5085156115255785821015611525576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b54831015801561157c5750603754600160a01b900460ff16155b1561158b57611589611994565b505b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b1580156115de57600080fd5b505af11580156115f2573d6000803e3d6000fd5b506000925050505b8981101561165d5760008b8b8381811061161057fe5b905060200201356001600160a01b0316905061165433308c8c8681811061163357fe5b90506020020135846001600160a01b0316611b5d909392919063ffffffff16565b506001016115fa565b50603a54831061166f5761166f611bbd565b5050506001825550505050505050565b611687611099565b6116d8576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561179a57600080fd5b81019080805160405193929190846401000000008211156117ba57600080fd5b9083019060208201858111156117cf57600080fd5b82516401000000008111828201881017156117e957600080fd5b82525081516020918201929091019080838360005b838110156118165781810151838201526020016117fe565b50505050905090810190601f1680156118435780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561188e57600080fd5b505afa1580156118a2573d6000803e3d6000fd5b505050506040513d60208110156118b857600080fd5b505160ff169050600481108015906118d1575060128111155b610bf65760405162461bcd60e51b81526004018080602001828103825260298152602001806136106029913960400191505060405180910390fd5b6000808260000b13156119375761193083600084900b600a0a63ffffffff612e9f16565b925061195f565b60008260000b121561195f5761195c836000848103900b600a0a63ffffffff612ef816565b92505b5090919050565b600080611979858563ffffffff612e9f16565b905061198b818463ffffffff612ef816565b95945050505050565b603754600090600160a01b900460ff16156119e8576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3657600080fd5b505afa158015611a4a573d6000803e3d6000fd5b505050506040513d6020811015611a6057600080fd5b5051611a6e575060006106cf565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611ab357600080fd5b505afa158015611ac7573d6000803e3d6000fd5b505050506040513d6020811015611add57600080fd5b50519050611ae9612c17565b915080821115611b5957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611b4057600080fd5b505af1158015611b54573d6000803e3d6000fd5b505050505b5090565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bb7908590612f3a565b50505050565b6000611bc76130f2565b905080611bd45750610be9565b6000611bde6131de565b90506000611bf2838363ffffffff612e3e16565b9050600082611c1e57603954611c1790670de0b6b3a76400009063ffffffff61323016565b9050611c76565b611c4384611c3784603954612e9f90919063ffffffff16565b9063ffffffff612ef816565b905080670de0b6b3a76400001115611c6d57611c17670de0b6b3a76400008263ffffffff61323016565b50505050610be9565b80611c845750505050610be9565b60005b603454811015611e1357600060348281548110611ca057fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611cf357600080fd5b505afa158015611d07573d6000803e3d6000fd5b505050506040513d6020811015611d1d57600080fd5b5051905080611d2d575050611e0b565b6000611d3f828663ffffffff61327216565b6001600160a01b03808516600090815260406020819052902054919250168015801590611d6c5750600082115b15611e065780611d8c6001600160a01b038616828563ffffffff61328716565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b50505050505b505050505b600101611c87565b5060005b6036548110156120e557600060368281548110611e3057fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b158015611e7d57600080fd5b505afa158015611e91573d6000803e3d6000fd5b505050506040513d6020811015611ea757600080fd5b505190506001600160a01b038116156120db576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d6020811015611f1f57600080fd5b5051905080611fae57306001600160a01b0316630e5c011e60368681548110611f4457fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b158015611f9157600080fd5b505af1158015611fa5573d6000803e3d6000fd5b505050506120d9565b60008290506000816001600160a01b03166370a0823160368881548110611fd157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561201f57600080fd5b505afa158015612033573d6000803e3d6000fd5b505050506040513d602081101561204957600080fd5b505190508281106120d657306001600160a01b0316630e5c011e6036888154811061207057fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b1580156120bd57600080fd5b505af11580156120d1573d6000803e3d6000fd5b505050505b50505b505b5050600101611e17565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b03811661216c576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661217e6116fc565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36121bc816132de565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561220a57600080fd5b505afa15801561221e573d6000803e3d6000fd5b505050506040513d602081101561223457600080fd5b5051915060005b6036548110156123795760006036828154811061225457fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b1580156122aa57600080fd5b505afa1580156122be573d6000803e3d6000fd5b505050506040513d60208110156122d457600080fd5b5051156123705761236d816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561233457600080fd5b505afa158015612348573d6000803e3d6000fd5b505050506040513d602081101561235e57600080fd5b5051859063ffffffff612e3e16565b93505b5060010161223b565b5050919050565b6060600061238c610eec565b9050606061239a6001612c38565b90506060826040519080825280602002602001820160405280156123c8578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156123f7578160200160208202803883390190505b506040805186815260208088028201019091529091506000908190868015612429578160200160208202803883390190505b5060385490975015612468576000612452612710611c376038548c612e9f90919063ffffffff16565b9050612464898263ffffffff61323016565b9850505b60005b6034548110156125185760006124a16034838154811061248757fe5b6000918252602090912001546001600160a01b03166121bf565b905060006124b5603484815481106113f057fe5b9050818784815181106124c457fe5b602002602001018181525050808684815181106124dd57fe5b602090810291909101015261250c6124ff83601284900363ffffffff61190c16565b869063ffffffff612e3e16565b9450505060010161246b565b5060005b6034548110156125c957600086828151811061253457fe5b60200260200101519050670de0b6b3a76400008110156125595750670de0b6b3a76400005b60006125ab85611c378461259f8a888151811061257257fe5b60200260200101516012038c898151811061258957fe5b602002602001015161190c90919063ffffffff16565b9063ffffffff612e9f16565b90506125bd848263ffffffff612e3e16565b9350505060010161251c565b5060006125dc898363ffffffff61330216565b905060005b6034548110156126345761261584611c37848985815181106125ff57fe5b6020026020010151612e9f90919063ffffffff16565b89828151811061262157fe5b60209081029190910101526001016125e1565b5050505050505050919050565b60008211612696576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156126db57600080fd5b505afa1580156126ef573d6000803e3d6000fd5b505050506040513d602081101561270557600080fd5b505190506000612713612c17565b604154909150156127ce576000612730838363ffffffff61330216565b9050604154670de0b6b3a764000082116127615761275c670de0b6b3a76400008363ffffffff61323016565b612779565b61277982670de0b6b3a764000063ffffffff61323016565b11156127cc576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a1606061281485612380565b905060005b603454811015612aaa5781818151811061282f57fe5b60200260200101516000141561284457612aa2565b60006034828154811061285357fe5b60009182526020909120015483516001600160a01b03909116915083908390811061287a57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128d857600080fd5b505afa1580156128ec573d6000803e3d6000fd5b505050506040513d602081101561290257600080fd5b50511061293f5761293a3384848151811061291957fe5b6020026020010151836001600160a01b03166132879092919063ffffffff16565b612aa0565b6000604060006034858154811061295257fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612a5f576000819050806001600160a01b031663d9caed1233603487815481106129a757fe5b9060005260206000200160009054906101000a90046001600160a01b03168888815181106129d157fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612a4157600080fd5b505af1158015612a55573d6000803e3d6000fd5b5050505050612a9e565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b600101612819565b508315612b58576000805b8251811015612b00576000612ad0603483815481106113f057fe5b9050612af5612ae88260120386858151811061258957fe5b849063ffffffff612e3e16565b925050600101612ab5565b5084811015612b56576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612bab57600080fd5b505af1158015612bbf573d6000803e3d6000fd5b50505050603b5485118015612bde5750603754600160a01b900460ff16155b156120e557612beb611994565b505050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b60006106cc612c246131de565b612c2c6130f2565b9063ffffffff612e3e16565b6060612c42610eec565b604051908082528060200260200182016040528015612c6b578160200160208202803883390190505b506037549091506001600160a01b031660005b603454811015612379576060612cb460348381548110612c9a57fe5b6000918252602090912001546001600160a01b0316611721565b90508415612dbc57612d9f600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d1d578181015183820152602001612d05565b50505050905090810190601f168015612d4a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612d6757600080fd5b505afa158015612d7b573d6000803e3d6000fd5b505050506040513d6020811015612d9157600080fd5b50519063ffffffff61190c16565b848381518110612dab57fe5b602002602001018181525050612e35565b60405163019af6bf60e41b8152602060048201818152835160248401528351612e1c93600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612d1d578181015183820152602001612d05565b848381518110612e2857fe5b6020026020010181815250505b50600101612c7e565b600082820183811015612e98576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082612eae57506000610bf6565b82820282848281612ebb57fe5b0414612e985760405162461bcd60e51b81526004018080602001828103825260218152602001806136396021913960400191505060405180910390fd5b6000612e9883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613337565b612f4c826001600160a01b03166133d9565b612f9d576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612fdb5780518252601f199092019160209182019101612fbc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461303d576040519150601f19603f3d011682016040523d82523d6000602084013e613042565b606091505b509150915081613099576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611bb7578080602001905160208110156130b557600080fd5b5051611bb75760405162461bcd60e51b815260040180806020018281038252602a81526020018061365a602a913960400191505060405180910390fd5b6000805b603454811015611b595760006034828154811061310f57fe5b6000918252602082200154603480546001600160a01b03909216935061313991859081106113f057fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d60208110156131af57600080fd5b5051905080156131d3576131d06124ff82601285900363ffffffff61190c16565b94505b5050506001016130f6565b6000805b603654811015611b5957613226613219603683815481106131ff57fe5b6000918252602090912001546001600160a01b0316613412565b839063ffffffff612e3e16565b91506001016131e2565b6000612e9883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613595565b6000612e988383670de0b6b3a7640000611966565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526132d9908490612f3a565b505050565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061331d84670de0b6b3a764000063ffffffff612e9f16565b905061332f818463ffffffff612ef816565b949350505050565b600081836133c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613388578181015183820152602001613370565b50505050905090810190601f1680156133b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816133cf57fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061332f575050151592915050565b600081815b603454811015612379576000613433603483815481106113f057fe5b9050826001600160a01b031663aa388af66034848154811061345157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561349f57600080fd5b505afa1580156134b3573d6000803e3d6000fd5b505050506040513d60208110156134c957600080fd5b50511561358c576000836001600160a01b0316635f515226603485815481106134ee57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561353c57600080fd5b505afa158015613550573d6000803e3d6000fd5b505050506040513d602081101561356657600080fd5b50519050801561358a576135876124ff82601285900363ffffffff61190c16565b94505b505b50600101613417565b600081848411156135e75760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613388578181015183820152602001613370565b50505090039056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a72315820ab97d4c53e4ef80d280841f43291bad1192e147995980878462b60004ce5f35164736f6c634300050b0032", + "solcInputHash": "c3af786fe12b6b771320281cb59e3482", + "metadata": "{\"compiler\":{\"version\":\"0.5.11+commit.22be8592.mod\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"redeemFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"uniswapAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaultBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"trusteeFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllAssets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getStrategyCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"trusteeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebaseThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebasePaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"strategistAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"claimGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"checkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedeemOutputs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeemAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxSupplyDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"isSupportedAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoAllocateThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAssetCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetDefaultStrategies\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"allocate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rebase\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"priceProvider\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isGovernor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"transferGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"capitalPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_assets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mintMultiple\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImpl\",\"type\":\"address\"}],\"name\":\"setAdminImpl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"AssetSupported\",\"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\":\"_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\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"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\":[],\"name\":\"CapitalPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebasePaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebaseUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vaultBuffer\",\"type\":\"uint256\"}],\"name\":\"VaultBufferUpdated\",\"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\":\"_priceProvider\",\"type\":\"address\"}],\"name\":\"PriceProviderUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"AllocateThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"RebaseThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"UniswapUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"StrategistUpdated\",\"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\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_yield\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"YieldDistribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"TrusteeFeeBpsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"TrusteeAddressChanged\",\"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\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"GovernorshipTransferred\",\"type\":\"event\"}],\"devdoc\":{\"methods\":{\"allocate()\":{\"details\":\"Allocate unallocated funds on Vault to strategies.*\"},\"checkBalance(address)\":{\"params\":{\"_asset\":\"Address of asset\"},\"return\":\"uint256 Balance of asset in decimals of asset\"},\"claimGovernance()\":{\"details\":\"Claim Governance of the contract to a new account (`newGovernor`). Can only be called by the new Governor.\"},\"getAllAssets()\":{\"details\":\"Return all asset addresses in order\"},\"getAssetCount()\":{\"details\":\"Return the number of assets suppported by the Vault.\"},\"getStrategyCount()\":{\"details\":\"Return the number of strategies active on the Vault.\"},\"governor()\":{\"details\":\"Returns the address of the current Governor.\"},\"isGovernor()\":{\"details\":\"Returns true if the caller is the current Governor.\"},\"mint(address,uint256,uint256)\":{\"details\":\"Deposit a supported asset and mint OUSD.\",\"params\":{\"_amount\":\"Amount of the asset being deposited\",\"_asset\":\"Address of the asset being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"mintMultiple(address[],uint256[],uint256)\":{\"details\":\"Mint for multiple assets in the same call.\",\"params\":{\"_amounts\":\"Amount of each asset at the same index in the _assets to deposit.\",\"_assets\":\"Addresses of assets being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"rebase()\":{\"details\":\"Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD.\"},\"redeem(uint256,uint256)\":{\"details\":\"Withdraw a supported asset and burn OUSD.\",\"params\":{\"_amount\":\"Amount of OUSD to burn\",\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"redeemAll(uint256)\":{\"params\":{\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"setAdminImpl(address)\":{\"details\":\"set the implementation for the admin, this needs to be in a base class else we cannot set it\",\"params\":{\"newImpl\":\"address of the implementation\"}},\"totalValue()\":{\"details\":\"Determine the total value of assets held by the vault and its strategies.\",\"return\":\"uint256 value Total value in USD (1e18)\"},\"transferGovernance(address)\":{\"details\":\"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\",\"params\":{\"_newGovernor\":\"Address of the new Governor\"}}}},\"userdoc\":{\"methods\":{\"allocate()\":{\"notice\":\"Allocate unallocated funds on Vault to strategies.\"},\"calculateRedeemOutputs(uint256)\":{\"notice\":\"Calculate the outputs for a redeem function, i.e. the mix of coins that will be returned\"},\"checkBalance(address)\":{\"notice\":\"Get the balance of an asset held in Vault and all strategies.\"},\"redeemAll(uint256)\":{\"notice\":\"Withdraw a supported asset and burn all OUSD.\"}}}},\"settings\":{\"compilationTarget\":{\"contracts/vault/VaultCore.sol\":\"VaultCore\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x640b6dee7a4b830bdfd52b5031a07fc2b12209f5b2e29e5d364a7d37f69d8076\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\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(address sender, address recipient, uint256 amount) 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\":\"0xe5bb0f57cff3e299f360052ba50f1ea0fff046df2be070b6943e0e3c3fdad8a9\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6f2c9955d65c522b80f4b8792f076512d2df947d2112cbc4d98a4781ed42ede2\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\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 * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1a8e5072509c5ea7365eb1d48030b9be865140c8fb779968da0a459a0e174a11\"},\"@openzeppelin/upgrades/contracts/Initializable.sol\":{\"content\":\"pragma solidity >=0.4.24 <0.7.0;\\n\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\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 use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || isConstructor() || !initialized, \\\"Contract instance has already been initialized\\\");\\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 /// @dev Returns true if and only if the function is running in the constructor\\n function isConstructor() private view returns (bool) {\\n // extcodesize checks the size of the code stored in an address, and\\n // address returns the current address. Since the code is still not\\n // deployed when running a constructor, any checks on its code size will\\n // yield zero, making it an effective way to detect if a contract is\\n // under construction or not.\\n address self = address(this);\\n uint256 cs;\\n assembly { cs := extcodesize(self) }\\n return cs == 0;\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0x9bfec92e36234ecc99b5d37230acb6cd1f99560233753162204104a4897e8721\"},\"contracts/governance/Governable.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Governable Contract\\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\\n private constant governorPosition = 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\\n\\n // keccak256(\\\"OUSD.pending.governor\\\");\\n bytes32\\n private constant pendingGovernorPosition = 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\\n\\n // keccak256(\\\"OUSD.reentry.status\\\");\\n bytes32\\n private constant reentryStatusPosition = 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() internal {\\n _setGovernor(msg.sender);\\n emit GovernorshipTransferred(address(0), _governor());\\n }\\n\\n /**\\n * @dev 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 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 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 * @dev 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 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 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 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 assembly {\\n sstore(position, _NOT_ENTERED)\\n }\\n }\\n\\n function _setPendingGovernor(address newGovernor) internal {\\n bytes32 position = pendingGovernorPosition;\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0x3e51ea48102945bf4b305bf9722a07514a585a29555d92f8c84352d1a4cfcee1\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x01eab42b6d54fa5389598e0663c24680ecc017e2da848e8ea1c40aeaa8225eef\"},\"contracts/interfaces/IMinMaxOracle.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IMinMaxOracle {\\n //Assuming 8 decimals\\n function priceMin(string calldata symbol) external view returns (uint256);\\n\\n function priceMax(string calldata symbol) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x164c8759ca5a8e39bbe1de6b2504098c543b2f15663c9d452e083418f8313f48\"},\"contracts/interfaces/IStrategy.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 Lending 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 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 collectRewardToken() external;\\n\\n /**\\n * @dev The address of the reward token for the Strategy.\\n */\\n function rewardTokenAddress() external pure returns (address);\\n\\n /**\\n * @dev The threshold (denominated in the reward token) over which the\\n * vault will auto harvest on allocate calls.\\n */\\n function rewardLiquidationThreshold() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9ef9546d60635c630e3446f270bc93f34593f5c77db8c671146f6c1eb0b2774\"},\"contracts/interfaces/IVault.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IVault {\\n event AssetSupported(address _asset);\\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 DepositsPaused();\\n event DepositsUnpaused();\\n\\n // Governable.sol\\n function transferGovernance(address _newGovernor) external;\\n\\n function claimGovernance() external;\\n\\n function governor() external view returns (address);\\n\\n // VaultAdmin.sol\\n function setPriceProvider(address _priceProvider) external;\\n\\n function priceProvider() external view returns (address);\\n\\n function setRedeemFeeBps(uint256 _redeemFeeBps) external;\\n\\n function redeemFeeBps() external view returns (uint256);\\n\\n function setVaultBuffer(uint256 _vaultBuffer) external;\\n\\n function vaultBuffer() external view returns (uint256);\\n\\n function setAutoAllocateThreshold(uint256 _threshold) external;\\n\\n function autoAllocateThreshold() external view returns (uint256);\\n\\n function setRebaseThreshold(uint256 _threshold) external;\\n\\n function rebaseThreshold() external view returns (uint256);\\n\\n function setStrategistAddr(address _address) external;\\n\\n function strategistAddr() external view returns (address);\\n\\n function setUniswapAddr(address _address) external;\\n\\n function uniswapAddr() external view returns (address);\\n\\n function setMaxSupplyDiff(uint256 _maxSupplyDiff) external;\\n\\n function maxSupplyDiff() external view returns (uint256);\\n\\n function setTrusteeAddress(address _address) external;\\n\\n function trusteeAddress() external view returns (address);\\n\\n function setTrusteeFeeBps(uint256 _basis) external;\\n\\n function trusteeFeeBps() external view returns (uint256);\\n\\n function supportAsset(address _asset) external;\\n\\n function approveStrategy(address _addr) external;\\n\\n function removeStrategy(address _addr) external;\\n\\n function setAssetDefaultStrategy(address _asset, address _strategy)\\n external;\\n\\n function assetDefaultStrategies(address _asset)\\n external\\n view\\n returns (address);\\n\\n function pauseRebase() external;\\n\\n function unpauseRebase() external;\\n\\n function rebasePaused() external view returns (bool);\\n\\n function pauseCapital() external;\\n\\n function unpauseCapital() external;\\n\\n function capitalPaused() external view returns (bool);\\n\\n function transferToken(address _asset, uint256 _amount) external;\\n\\n function harvest() external;\\n\\n function harvest(address _strategyAddr) external;\\n\\n function priceUSDMint(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n function priceUSDRedeem(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n // VaultCore.sol\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount) external;\\n\\n function redeemAll(uint256 _minimumUnitAmount) external;\\n\\n function allocate() external;\\n\\n function reallocate(\\n address _strategyFromAddress,\\n address _strategyToAddress,\\n address[] calldata _assets,\\n uint256[] calldata _amounts\\n ) external;\\n\\n function rebase() external;\\n\\n function totalValue() external view returns (uint256 value);\\n\\n function checkBalance() external view returns (uint256);\\n\\n function checkBalance(address _asset) external view returns (uint256);\\n\\n function calculateRedeemOutputs(uint256 _amount)\\n external\\n view\\n returns (uint256[] memory);\\n\\n function getAssetCount() external view returns (uint256);\\n\\n function getAllAssets() external view returns (address[] memory);\\n\\n function getStrategyCount() external view returns (uint256);\\n\\n function isSupportedAsset(address _asset) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x84271ee5504677f7ad8b808df40d16704d5e2b83a9cdb897208d8c7b3e6cb8bb\"},\"contracts/token/OUSD.sol\":{\"content\":\"pragma solidity 0.5.11;\\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/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport {\\n InitializableERC20Detailed\\n} 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 TotalSupplyUpdated(\\n uint256 totalSupply,\\n uint256 rebasingCredits,\\n uint256 rebasingCreditsPerToken\\n );\\n\\n enum RebaseOptions { NotSet, OptOut, OptIn }\\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 public rebasingCredits;\\n uint256 public 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\\n function initialize(\\n string calldata _nameArg,\\n string calldata _symbolArg,\\n address _vaultAddress\\n ) external onlyGovernor initializer {\\n InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);\\n rebasingCreditsPerToken = 1e18;\\n vaultAddress = _vaultAddress;\\n }\\n\\n /**\\n * @dev Verifies that the caller is the Savings Manager 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 returns (uint256) {\\n return _totalSupply;\\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) public view returns (uint256) {\\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 * @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 return (_creditBalances[_account], _creditsPerToken(_account));\\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) public returns (bool) {\\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 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 an owner has allowed to a _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 returns (uint256)\\n {\\n return _allowances[_owner][_spender];\\n }\\n\\n /**\\n * @dev Approve the passed address to spend the specified _amount of tokens on behalf of\\n * msg.sender. This method is included for ERC20 compatibility.\\n * increaseAllowance and decreaseAllowance should be used instead.\\n * Changing an allowance with this method brings the risk that someone may transfer both\\n * the old and the new allowance - if they are both greater than zero - if a transfer\\n * transaction is mined before the later approve() call is mined.\\n *\\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) public returns (bool) {\\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 a _spender.\\n * This method should be used instead of approve() to avoid the double approval vulnerability\\n * 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 a _spender.\\n * @param _spender The address which will spend the funds.\\n * @param _subtractedValue The _amount of tokens to decrease the allowance 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 // 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(_creditBalances[_account]);\\n }\\n }\\n\\n /**\\n * @dev Add a contract address to the non rebasing exception list. I.e. the\\n * address's balance will be part of rebases so the account will be exposed\\n * to upside and downside.\\n */\\n function rebaseOptIn() public nonReentrant {\\n require(_isNonRebasingAccount(msg.sender), \\\"Account has not opted out\\\");\\n\\n // Convert balance into the same amount at the current exchange rate\\n uint256 newCreditBalance = _creditBalances[msg.sender]\\n .mul(rebasingCreditsPerToken)\\n .div(_creditsPerToken(msg.sender));\\n\\n // Decreasing non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.sub(balanceOf(msg.sender));\\n\\n _creditBalances[msg.sender] = newCreditBalance;\\n\\n // Increase rebasing credits, totalSupply remains unchanged so no\\n // adjustment necessary\\n rebasingCredits = rebasingCredits.add(_creditBalances[msg.sender]);\\n\\n rebaseState[msg.sender] = RebaseOptions.OptIn;\\n\\n // Delete any fixed credits per token\\n delete nonRebasingCreditsPerToken[msg.sender];\\n }\\n\\n /**\\n * @dev Remove a contract address to the non rebasing exception list.\\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 }\\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 * @return uint256 representing the new total supply.\\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 TotalSupplyUpdated(\\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 TotalSupplyUpdated(\\n _totalSupply,\\n rebasingCredits,\\n rebasingCreditsPerToken\\n );\\n }\\n}\\n\",\"keccak256\":\"0xea89a8b152b363982ba8db340b1e20c3194b2e75a06630cbbf43e3c50fff61a4\"},\"contracts/utils/Helpers.sol\":{\"content\":\"pragma solidity 0.5.11;\\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\":\"0xd2ca92e0af883dc1aec5b22caced274e59829e0e30a9e955dcc48b8d921f5cdc\"},\"contracts/utils/InitializableERC20Detailed.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 */\\ncontract 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 * @dev Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0x7919369d0f3bd74b4f0ee78a682afe43f91b186cdd0708e303068e4feeb29007\"},\"contracts/utils/StableMath.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/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 adjustment Amount to adjust by e.g. scaleBy(1e18, -1) == 1e17\\n */\\n function scaleBy(uint256 x, int8 adjustment)\\n internal\\n pure\\n returns (uint256)\\n {\\n if (adjustment > 0) {\\n x = x.mul(10**uint256(adjustment));\\n } else if (adjustment < 0) {\\n x = x.div(10**uint256(adjustment * -1));\\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 9e38 / 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\":\"0xa77fccf850feb6d54ba3a6530f92554caef8a67a1ceb573d4f8a5d1bf64ff9d2\"},\"contracts/vault/VaultCore.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Vault Contract\\n * @notice The Vault contract stores assets. On a deposit, OUSD will be minted\\n and sent to the depositor. On a withdrawal, OUSD will be burned and\\n assets will be sent to the withdrawer. The Vault accepts deposits of\\n interest form yield bearing strategies which will modify the supply\\n of OUSD.\\n * @author Origin Protocol Inc\\n */\\n\\nimport \\\"./VaultStorage.sol\\\";\\nimport { IMinMaxOracle } from \\\"../interfaces/IMinMaxOracle.sol\\\";\\nimport { IVault } from \\\"../interfaces/IVault.sol\\\";\\n\\ncontract VaultCore is VaultStorage {\\n uint256 constant MAX_UINT = 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 /**\\n * @dev Deposit a supported asset and mint OUSD.\\n * @param _asset Address of the asset being deposited\\n * @param _amount Amount of the asset being deposited\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(assets[_asset].isSupported, \\\"Asset is not supported\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 price = IMinMaxOracle(priceProvider).priceMin(\\n Helpers.getSymbol(_asset)\\n );\\n if (price > 1e8) {\\n price = 1e8;\\n }\\n uint256 assetDecimals = Helpers.getDecimals(_asset);\\n uint256 unitAdjustedDeposit = _amount.scaleBy(int8(18 - assetDecimals));\\n uint256 priceAdjustedDeposit = _amount.mulTruncateScale(\\n price.scaleBy(int8(10)), // 18-8 because oracles have 8 decimals precision\\n 10**assetDecimals\\n );\\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 (unitAdjustedDeposit >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n // Mint matching OUSD\\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 (unitAdjustedDeposit >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Mint for multiple assets in the same call.\\n * @param _assets Addresses of assets being deposited\\n * @param _amounts Amount of each asset at the same index in the _assets\\n * to deposit.\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amounts,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(_assets.length == _amounts.length, \\\"Parameter length mismatch\\\");\\n\\n uint256 unitAdjustedTotal = 0;\\n uint256 priceAdjustedTotal = 0;\\n uint256[] memory assetPrices = _getAssetPrices(false);\\n for (uint256 j = 0; j < _assets.length; j++) {\\n // In memoriam\\n require(assets[_assets[j]].isSupported, \\\"Asset is not supported\\\");\\n require(_amounts[j] > 0, \\\"Amount must be greater than 0\\\");\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (_assets[j] == allAssets[i]) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n uint256 price = assetPrices[i];\\n if (price > 1e18) {\\n price = 1e18;\\n }\\n unitAdjustedTotal = unitAdjustedTotal.add(\\n _amounts[j].scaleBy(int8(18 - assetDecimals))\\n );\\n priceAdjustedTotal = priceAdjustedTotal.add(\\n _amounts[j].mulTruncateScale(price, 10**assetDecimals)\\n );\\n }\\n }\\n }\\n\\n if (_minimumOusdAmount > 0) {\\n require(\\n priceAdjustedTotal >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n }\\n\\n emit Mint(msg.sender, priceAdjustedTotal);\\n\\n // Rebase must happen before any transfers occur.\\n if (unitAdjustedTotal >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n oUSD.mint(msg.sender, priceAdjustedTotal);\\n\\n for (uint256 i = 0; i < _assets.length; i++) {\\n IERC20 asset = IERC20(_assets[i]);\\n asset.safeTransferFrom(msg.sender, address(this), _amounts[i]);\\n }\\n\\n if (unitAdjustedTotal >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n public\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(_amount, _minimumUnitAmount);\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount) internal {\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 _totalSupply = oUSD.totalSupply();\\n uint256 _backingValue = _totalValue();\\n\\n if (maxSupplyDiff > 0) {\\n // Allow a max difference of maxSupplyDiff% between\\n // backing assets value and OUSD total supply\\n uint256 diff = _totalSupply.divPrecisely(_backingValue);\\n\\n require(\\n (diff > 1e18 ? diff.sub(1e18) : uint256(1e18).sub(diff)) <=\\n maxSupplyDiff,\\n \\\"Backing supply liquidity error\\\"\\n );\\n }\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // Calculate redemption outputs\\n uint256[] memory outputs = _calculateRedeemOutputs(_amount);\\n // Send outputs\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (outputs[i] == 0) continue;\\n\\n IERC20 asset = IERC20(allAssets[i]);\\n\\n if (asset.balanceOf(address(this)) >= outputs[i]) {\\n // Use Vault funds first if sufficient\\n asset.safeTransfer(msg.sender, outputs[i]);\\n } else {\\n address strategyAddr = assetDefaultStrategies[allAssets[i]];\\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, allAssets[i], 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 uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n unitTotal = unitTotal.add(\\n outputs[i].scaleBy(int8(18 - assetDecimals))\\n );\\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 if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn all OUSD.\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeemAll(uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n // Unfortunately we have to do balanceOf twice, the rebase may change\\n // the account balance\\n if (oUSD.balanceOf(msg.sender) > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\n * @dev Allocate unallocated funds on Vault to strategies.\\n **/\\n function allocate() public whenNotCapitalPaused nonReentrant {\\n _allocate();\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\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.add(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).sub(vaultBuffer);\\n } else {\\n vaultBufferModifier = vaultBuffer.mul(calculatedTotalValue).div(\\n vaultValue\\n );\\n if (1e18 > vaultBufferModifier) {\\n // E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17\\n // (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault\\n vaultBufferModifier = uint256(1e18).sub(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 the the appropriate\\n // strategy\\n for (uint256 i = 0; i < allAssets.length; 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[address(\\n 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 }\\n }\\n\\n // Harvest for all reward tokens above reward liquidation threshold\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n address rewardTokenAddress = strategy.rewardTokenAddress();\\n if (rewardTokenAddress != address(0)) {\\n uint256 liquidationThreshold = strategy\\n .rewardLiquidationThreshold();\\n if (liquidationThreshold == 0) {\\n // No threshold set, always harvest from strategy\\n IVault(address(this)).harvest(allStrategies[i]);\\n } else {\\n // Check balance against liquidation threshold\\n // Note some strategies don't hold the reward token balance\\n // on their contract so the liquidation threshold should be\\n // set to 0\\n IERC20 rewardToken = IERC20(rewardTokenAddress);\\n uint256 rewardTokenAmount = rewardToken.balanceOf(\\n allStrategies[i]\\n );\\n if (rewardTokenAmount >= liquidationThreshold) {\\n IVault(address(this)).harvest(allStrategies[i]);\\n }\\n }\\n }\\n }\\n }\\n\\n /**\\n * @dev Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OUSD.\\n */\\n function rebase() public whenNotRebasePaused 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 OUSD, optionaly sending a\\n * portion of the yield to the trustee.\\n */\\n function _rebase() internal whenNotRebasePaused {\\n uint256 ousdSupply = oUSD.totalSupply();\\n if (ousdSupply == 0) {\\n return;\\n }\\n uint256 vaultValue = _totalValue();\\n\\n // Yield fee collection\\n address _trusteeAddress = trusteeAddress; // gas savings\\n if (_trusteeAddress != address(0) && (vaultValue > ousdSupply)) {\\n uint256 yield = vaultValue.sub(ousdSupply);\\n uint256 fee = yield.mul(trusteeFeeBps).div(10000);\\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 OUSD supply upwards\\n ousdSupply = oUSD.totalSupply(); // Final check should use latest value\\n if (vaultValue > ousdSupply) {\\n oUSD.changeSupply(vaultValue);\\n }\\n }\\n\\n /**\\n * @dev Determine the total value of assets held by the vault and its\\n * strategies.\\n * @return uint256 value Total value in USD (1e18)\\n */\\n function totalValue() external view 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 uint256 value Total value in USD (1e18)\\n */\\n function _totalValue() internal view returns (uint256 value) {\\n return _totalValueInVault().add(_totalValueInStrategies());\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Vault.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInVault() internal view returns (uint256 value) {\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n IERC20 asset = IERC20(allAssets[y]);\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n uint256 balance = asset.balanceOf(address(this));\\n if (balance > 0) {\\n value = value.add(balance.scaleBy(int8(18 - assetDecimals)));\\n }\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Strategies.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategies() internal view returns (uint256 value) {\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n value = value.add(_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 uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategy(address _strategyAddr)\\n internal\\n view\\n returns (uint256 value)\\n {\\n IStrategy strategy = IStrategy(_strategyAddr);\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n if (strategy.supportsAsset(allAssets[y])) {\\n uint256 balance = strategy.checkBalance(allAssets[y]);\\n if (balance > 0) {\\n value = value.add(\\n balance.scaleBy(int8(18 - assetDecimals))\\n );\\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 uint256 Balance of asset in decimals of asset\\n */\\n function _checkBalance(address _asset)\\n internal\\n view\\n returns (uint256 balance)\\n {\\n IERC20 asset = IERC20(_asset);\\n balance = asset.balanceOf(address(this));\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n if (strategy.supportsAsset(_asset)) {\\n balance = balance.add(strategy.checkBalance(_asset));\\n }\\n }\\n }\\n\\n /**\\n * @notice Get the balance of all assets held in Vault and all strategies.\\n * @return uint256 Balance of all assets (1e18)\\n */\\n function _checkBalance() internal view returns (uint256 balance) {\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n balance = balance.add(\\n _checkBalance(allAssets[i]).scaleBy(int8(18 - assetDecimals))\\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 * @notice Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned.\\n * @return 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 = getAssetCount();\\n uint256[] memory assetPrices = _getAssetPrices(true);\\n uint256[] memory assetBalances = new uint256[](assetCount);\\n uint256[] memory assetDecimals = new uint256[](assetCount);\\n uint256 totalBalance = 0;\\n uint256 totalOutputRatio = 0;\\n outputs = new uint256[](assetCount);\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mul(redeemFeeBps).div(10000);\\n _amount = _amount.sub(redeemFee);\\n }\\n\\n // Calculate assets balances and decimals once,\\n // for a large gas savings.\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 balance = _checkBalance(allAssets[i]);\\n uint256 decimals = Helpers.getDecimals(allAssets[i]);\\n assetBalances[i] = balance;\\n assetDecimals[i] = decimals;\\n totalBalance = totalBalance.add(\\n balance.scaleBy(int8(18 - decimals))\\n );\\n }\\n // Calculate totalOutputRatio\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 price = assetPrices[i];\\n // Never give out more than one\\n // stablecoin per dollar of OUSD\\n if (price < 1e18) {\\n price = 1e18;\\n }\\n uint256 ratio = assetBalances[i]\\n .scaleBy(int8(18 - assetDecimals[i]))\\n .mul(price)\\n .div(totalBalance);\\n totalOutputRatio = totalOutputRatio.add(ratio);\\n }\\n // Calculate final outputs\\n uint256 factor = _amount.divPrecisely(totalOutputRatio);\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n outputs[i] = assetBalances[i].mul(factor).div(totalBalance);\\n }\\n }\\n\\n /**\\n * @notice Get an array of the supported asset prices in USD.\\n * @return uint256[] Array of asset prices in USD (1e18)\\n */\\n function _getAssetPrices(bool useMax)\\n internal\\n view\\n returns (uint256[] memory assetPrices)\\n {\\n assetPrices = new uint256[](getAssetCount());\\n\\n IMinMaxOracle oracle = IMinMaxOracle(priceProvider);\\n // Price from Oracle is returned with 8 decimals\\n // _amount is in assetDecimals\\n\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n string memory symbol = Helpers.getSymbol(allAssets[i]);\\n // Get all the USD prices of the asset in 1e18\\n if (useMax) {\\n assetPrices[i] = oracle.priceMax(symbol).scaleBy(int8(18 - 8));\\n } else {\\n assetPrices[i] = oracle.priceMin(symbol).scaleBy(int8(18 - 8));\\n }\\n }\\n }\\n\\n /***************************************\\n Utils\\n ****************************************/\\n\\n /**\\n * @dev Return the number of assets suppported by the Vault.\\n */\\n function getAssetCount() public view returns (uint256) {\\n return allAssets.length;\\n }\\n\\n /**\\n * @dev Return all asset addresses in order\\n */\\n function getAllAssets() external view returns (address[] memory) {\\n return allAssets;\\n }\\n\\n /**\\n * @dev Return the number of strategies active on the Vault.\\n */\\n function getStrategyCount() external view returns (uint256) {\\n return allStrategies.length;\\n }\\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 function() external payable {\\n bytes32 slot = adminImplPosition;\\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(gas, sload(slot), 0, calldatasize, 0, 0)\\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\",\"keccak256\":\"0x9af2d88c824d11589927a4f7c1f60157ead5ca26352a4171139ece27a3b5b22d\"},\"contracts/vault/VaultStorage.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD 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/SafeERC20.sol\\\";\\nimport { SafeMath } from \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.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 \\\"../utils/Helpers.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\n\\ncontract VaultStorage is Initializable, Governable {\\n using SafeMath for uint256;\\n using StableMath for uint256;\\n using SafeMath for int256;\\n using SafeERC20 for IERC20;\\n\\n event AssetSupported(address _asset);\\n event AssetDefaultStrategyUpdated(address _asset, address _strategy);\\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 RedeemFeeUpdated(uint256 _redeemFeeBps);\\n event PriceProviderUpdated(address _priceProvider);\\n event AllocateThresholdUpdated(uint256 _threshold);\\n event RebaseThresholdUpdated(uint256 _threshold);\\n event UniswapUpdated(address _address);\\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\\n // Assets supported by the Vault, i.e. Stablecoins\\n struct Asset {\\n bool isSupported;\\n }\\n mapping(address => Asset) assets;\\n address[] allAssets;\\n\\n // Strategies approved for use by the Vault\\n struct Strategy {\\n bool isSupported;\\n uint256 _deprecated; // Deprecated storage slot\\n }\\n mapping(address => Strategy) strategies;\\n address[] allStrategies;\\n\\n // Address of the Oracle price provider contract\\n address public priceProvider;\\n // Pausing bools\\n bool public rebasePaused = false;\\n bool public capitalPaused = true;\\n // Redemption fee in basis points\\n uint256 public redeemFeeBps;\\n // Buffer of assets to keep in Vault to handle (most) withdrawals\\n uint256 public vaultBuffer;\\n // Mints over this amount automatically allocate funds. 18 decimals.\\n uint256 public autoAllocateThreshold;\\n // Mints over this amount automatically rebase. 18 decimals.\\n uint256 public rebaseThreshold;\\n\\n OUSD oUSD;\\n\\n //keccak256(\\\"OUSD.vault.governor.admin.impl\\\");\\n bytes32 constant adminImplPosition = 0xa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9;\\n\\n // Address of the contract responsible for post rebase syncs with AMMs\\n address private _deprecated_rebaseHooksAddr = address(0);\\n\\n // Address of Uniswap\\n address public uniswapAddr = address(0);\\n\\n // Address of the Strategist\\n address public strategistAddr = address(0);\\n\\n // Mapping of asset address to the Strategy that they should automatically\\n // be allocated to\\n mapping(address => address) public assetDefaultStrategies;\\n\\n uint256 public maxSupplyDiff;\\n\\n // Trustee address that can collect a percentage of yield\\n address public trusteeAddress;\\n\\n // Amount of yield collected in basis points\\n uint256 public trusteeFeeBps;\\n\\n /**\\n * @dev 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 assembly {\\n sstore(position, newImpl)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02d224b70c086a3df5cf22792721aed5f278ddf4bc7b98b67ac9c38c767760a0\"}},\"version\":1}", + "bytecode": "0x60806040526037805461ffff60a01b19167501000000000000000000000000000000000000000000179055603d80546001600160a01b0319908116909155603e805482169055603f8054909116905562000062336001600160e01b03620000bb16565b620000756001600160e01b03620000ce16565b6001600160a01b031660006001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3620000e2565b600080516020620039e783398151915255565b600080516020620039e78339815191525490565b6138f580620000f26000396000f3fe6080604052600436106101d85760003560e01c80637136a7a611610102578063af14052c11610095578063d4c3eea011610064578063d4c3eea0146105d0578063e6cc5432146105e5578063f0efb4c7146105fa578063fc0cfeee146106c9576101d8565b8063af14052c1461055e578063b888879e14610573578063c7af335214610588578063d38bfff41461059d576101d8565b80639fa1826e116100d15780639fa1826e146104ec578063a0aead4d14610501578063a403e4d514610516578063abaa991614610549576101d8565b80637136a7a61461044a5780637cbc2373146104745780638e510b52146104a45780639be918e6146104b9576101d8565b806331e19cfa1161017a578063570d8e1d11610149578063570d8e1d146103c35780635d36b190146103d85780635f515226146103ed57806367bd7ba314610420576101d8565b806331e19cfa1461035b57806349c1d54d1461037057806352d38e5d1461038557806353ca9f241461039a576101d8565b8063156e29f6116101b6578063156e29f61461028b5780631edfe3da146102cc578063207134b0146102e15780632acada4d146102f6576101d8565b806309f6442c1461021e5780630c340a2414610245578063128a8b0514610276575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610219573d6000f35b3d6000fd5b34801561022a57600080fd5b506102336106fc565b60408051918252519081900360200190f35b34801561025157600080fd5b5061025a610702565b604080516001600160a01b039092168252519081900360200190f35b34801561028257600080fd5b5061025a610711565b34801561029757600080fd5b506102ca600480360360608110156102ae57600080fd5b506001600160a01b038135169060208101359060400135610720565b005b3480156102d857600080fd5b50610233610b33565b3480156102ed57600080fd5b50610233610b39565b34801561030257600080fd5b5061030b610b3f565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561034757818101518382015260200161032f565b505050509050019250505060405180910390f35b34801561036757600080fd5b50610233610ba1565b34801561037c57600080fd5b5061025a610ba7565b34801561039157600080fd5b50610233610bb6565b3480156103a657600080fd5b506103af610bbc565b604080519115158252519081900360200190f35b3480156103cf57600080fd5b5061025a610bcc565b3480156103e457600080fd5b506102ca610bdb565b3480156103f957600080fd5b506102336004803603602081101561041057600080fd5b50356001600160a01b0316610c3d565b34801561042c57600080fd5b5061030b6004803603602081101561044357600080fd5b5035610c4e565b34801561045657600080fd5b506102ca6004803603602081101561046d57600080fd5b5035610c59565b34801561048057600080fd5b506102ca6004803603604081101561049757600080fd5b5080359060200135610e29565b3480156104b057600080fd5b50610233610f10565b3480156104c557600080fd5b506103af600480360360208110156104dc57600080fd5b50356001600160a01b0316610f16565b3480156104f857600080fd5b50610233610f34565b34801561050d57600080fd5b50610233610f3a565b34801561052257600080fd5b5061025a6004803603602081101561053957600080fd5b50356001600160a01b0316610f40565b34801561055557600080fd5b506102ca610f5b565b34801561056a57600080fd5b506102ca611016565b34801561057f57600080fd5b5061025a6110cb565b34801561059457600080fd5b506103af6110da565b3480156105a957600080fd5b506102ca600480360360208110156105c057600080fd5b50356001600160a01b03166110fd565b3480156105dc57600080fd5b506102336111a9565b3480156105f157600080fd5b506103af6111b3565b34801561060657600080fd5b506102ca6004803603606081101561061d57600080fd5b81019060208101813564010000000081111561063857600080fd5b82018360208201111561064a57600080fd5b8035906020019184602083028401116401000000008311171561066c57600080fd5b91939092909160208101903564010000000081111561068a57600080fd5b82018360208201111561069c57600080fd5b803590602001918460208302840111640100000000831117156106be57600080fd5b9193509150356111c3565b3480156106d557600080fd5b506102ca600480360360208110156106ec57600080fd5b50356001600160a01b03166116be565b60385481565b600061070c61177f565b905090565b603e546001600160a01b031681565b603754600160a81b900460ff1615610770576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156107c8576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff16610832576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610887576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf06108a4886117a4565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108f05781810151838201526020016108d8565b50505050905090810190601f16801561091d5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d602081101561096457600080fd5b505190506305f5e10081111561097b57506305f5e1005b6000610986876118d5565b9050600061099e87601284900363ffffffff61198f16565b905060006109c86109b685600a63ffffffff61198f16565b8990600a86900a63ffffffff6119e916565b90508615610a255786811015610a25576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a7c5750603754600160a01b900460ff16155b15610a8957610a89611a17565b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610adc57600080fd5b505af1158015610af0573d6000803e3d6000fd5b508b9250610b129150506001600160a01b03821633308c63ffffffff611d3e16565b603a548310610b2357610b23611d9e565b5050505050600182555050505050565b60395481565b60435481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b9757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b79575b5050505050905090565b60365490565b6042546001600160a01b031681565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610be36122c1565b6001600160a01b0316336001600160a01b031614610c325760405162461bcd60e51b81526004018080602001828103825260308152602001806138916030913960400191505060405180910390fd5b610c3b336122e6565b565b6000610c4882612394565b92915050565b6060610c4882612555565b603754600160a81b900460ff1615610ca9576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610d01576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d5357600080fd5b505afa158015610d67573d6000803e3d6000fd5b505050506040513d6020811015610d7d57600080fd5b5051118015610d965750603754600160a01b900460ff16155b15610da357610da3611a17565b603c54604080516370a0823160e01b81523360048201529051610e21926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610def57600080fd5b505afa158015610e03573d6000803e3d6000fd5b505050506040513d6020811015610e1957600080fd5b505184612816565b506001905550565b603754600160a81b900460ff1615610e79576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610ed1576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ef05750603754600160a01b900460ff16155b15610efd57610efd611a17565b610f078484612816565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610fab576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415611003576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611d9e565b5060019055565b603754600160a01b900460ff1615611067576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156110bf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611a17565b6037546001600160a01b031681565b60006110e461177f565b6001600160a01b0316336001600160a01b031614905090565b6111056110da565b611156576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61115f81612dc0565b806001600160a01b031661117161177f565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b600061070c612de4565b603754600160a81b900460ff1681565b603754600160a81b900460ff1615611213576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b78339815191528054600281141561126b576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282558584146112c3576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b60008060606112d182612e05565b905060005b8981101561150a57603360008c8c848181106112ee57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661135e576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061136c57fe5b90506020020135116113c5576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b60345481101561150157603481815481106113df57fe5b6000918252602090912001546001600160a01b03168c8c8481811061140057fe5b905060200201356001600160a01b03166001600160a01b031614156114f957600061144b6034838154811061143157fe5b6000918252602090912001546001600160a01b03166118d5565b9050600084838151811061145b57fe5b60200260200101519050670de0b6b3a76400008111156114805750670de0b6b3a76400005b6114b86114ab836012038e8e8881811061149657fe5b9050602002013561198f90919063ffffffff16565b889063ffffffff61300b16565b96506114f46114e78284600a0a8f8f898181106114d157fe5b905060200201356119e99092919063ffffffff16565b879063ffffffff61300b16565b955050505b6001016113c8565b506001016112d6565b5085156115665785821015611566576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b5483101580156115bd5750603754600160a01b900460ff16155b156115ca576115ca611a17565b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b15801561161d57600080fd5b505af1158015611631573d6000803e3d6000fd5b506000925050505b8981101561169c5760008b8b8381811061164f57fe5b905060200201356001600160a01b0316905061169333308c8c8681811061167257fe5b90506020020135846001600160a01b0316611d3e909392919063ffffffff16565b50600101611639565b50603a5483106116ae576116ae611d9e565b5050506001825550505050505050565b6116c66110da565b611717576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b6117208161306c565b61175b5760405162461bcd60e51b81526004018080602001828103825260248152602001806137d76024913960400191505060405180910390fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561181d57600080fd5b810190808051604051939291908464010000000082111561183d57600080fd5b90830190602082018581111561185257600080fd5b825164010000000081118282018810171561186c57600080fd5b82525081516020918201929091019080838360005b83811015611899578181015183820152602001611881565b50505050905090810190601f1680156118c65780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561191157600080fd5b505afa158015611925573d6000803e3d6000fd5b505050506040513d602081101561193b57600080fd5b505160ff16905060048110801590611954575060128111155b610c485760405162461bcd60e51b81526004018080602001828103825260298152602001806137fb6029913960400191505060405180910390fd5b6000808260000b13156119ba576119b383600084900b600a0a63ffffffff6130a816565b92506119e2565b60008260000b12156119e2576119df836000848103900b600a0a63ffffffff61310116565b92505b5090919050565b6000806119fc858563ffffffff6130a816565b9050611a0e818463ffffffff61310116565b95945050505050565b603754600160a01b900460ff1615611a68576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611aad57600080fd5b505afa158015611ac1573d6000803e3d6000fd5b505050506040513d6020811015611ad757600080fd5b5051905080611ae65750610c3b565b6000611af0612de4565b6042549091506001600160a01b03168015801590611b0d57508282115b15611c4f576000611b24838563ffffffff61314316565b90506000611b4f612710611b43604354856130a890919063ffffffff16565b9063ffffffff61310116565b9050808211611b8f5760405162461bcd60e51b81526004018080602001828103825260228152602001806138456022913960400191505060405180910390fd5b8015611c0357603c54604080516340c10f1960e01b81526001600160a01b03868116600483015260248201859052915191909216916340c10f1991604480830192600092919082900301818387803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b505050505b604080516001600160a01b03851681526020810184905280820183905290517f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809181900360600190a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9d57600080fd5b505afa158015611cb1573d6000803e3d6000fd5b505050506040513d6020811015611cc757600080fd5b5051925082821115611d3957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611d2057600080fd5b505af1158015611d34573d6000803e3d6000fd5b505050505b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611d98908590613185565b50505050565b6000611da861333d565b905080611db55750610c3b565b6000611dbf61342d565b90506000611dd3838363ffffffff61300b16565b9050600082611dff57603954611df890670de0b6b3a76400009063ffffffff61314316565b9050611e4b565b611e1884611b43846039546130a890919063ffffffff16565b905080670de0b6b3a76400001115611e4257611df8670de0b6b3a76400008263ffffffff61314316565b50505050610c3b565b80611e595750505050610c3b565b60005b603454811015611fe857600060348281548110611e7557fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611ec857600080fd5b505afa158015611edc573d6000803e3d6000fd5b505050506040513d6020811015611ef257600080fd5b5051905080611f02575050611fe0565b6000611f14828663ffffffff61347f16565b6001600160a01b03808516600090815260406020819052902054919250168015801590611f415750600082115b15611fdb5780611f616001600160a01b038616828563ffffffff61349416565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611fc157600080fd5b505af1158015611fd5573d6000803e3d6000fd5b50505050505b505050505b600101611e5c565b5060005b6036548110156122ba5760006036828154811061200557fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b15801561205257600080fd5b505afa158015612066573d6000803e3d6000fd5b505050506040513d602081101561207c57600080fd5b505190506001600160a01b038116156122b0576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b1580156120ca57600080fd5b505afa1580156120de573d6000803e3d6000fd5b505050506040513d60208110156120f457600080fd5b505190508061218357306001600160a01b0316630e5c011e6036868154811061211957fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561216657600080fd5b505af115801561217a573d6000803e3d6000fd5b505050506122ae565b60008290506000816001600160a01b03166370a08231603688815481106121a657fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156121f457600080fd5b505afa158015612208573d6000803e3d6000fd5b505050506040513d602081101561221e57600080fd5b505190508281106122ab57306001600160a01b0316630e5c011e6036888154811061224557fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561229257600080fd5b505af11580156122a6573d6000803e3d6000fd5b505050505b50505b505b5050600101611fec565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b038116612341576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661235361177f565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3612391816134e6565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b1580156123df57600080fd5b505afa1580156123f3573d6000803e3d6000fd5b505050506040513d602081101561240957600080fd5b5051915060005b60365481101561254e5760006036828154811061242957fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b15801561247f57600080fd5b505afa158015612493573d6000803e3d6000fd5b505050506040513d60208110156124a957600080fd5b50511561254557612542816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561250957600080fd5b505afa15801561251d573d6000803e3d6000fd5b505050506040513d602081101561253357600080fd5b5051859063ffffffff61300b16565b93505b50600101612410565b5050919050565b60606000612561610f3a565b9050606061256f6001612e05565b905060608260405190808252806020026020018201604052801561259d578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156125cc578160200160208202803883390190505b5060408051868152602080880282010190915290915060009081908680156125fe578160200160208202803883390190505b506038549097501561263d576000612627612710611b436038548c6130a890919063ffffffff16565b9050612639898263ffffffff61314316565b9850505b60005b6034548110156126ed5760006126766034838154811061265c57fe5b6000918252602090912001546001600160a01b0316612394565b9050600061268a6034848154811061143157fe5b90508187848151811061269957fe5b602002602001018181525050808684815181106126b257fe5b60209081029190910101526126e16126d483601284900363ffffffff61198f16565b869063ffffffff61300b16565b94505050600101612640565b5060005b60345481101561279e57600086828151811061270957fe5b60200260200101519050670de0b6b3a764000081101561272e5750670de0b6b3a76400005b600061278085611b43846127748a888151811061274757fe5b60200260200101516012038c898151811061275e57fe5b602002602001015161198f90919063ffffffff16565b9063ffffffff6130a816565b9050612792848263ffffffff61300b16565b935050506001016126f1565b5060006127b1898363ffffffff61350a16565b905060005b603454811015612809576127ea84611b43848985815181106127d457fe5b60200260200101516130a890919063ffffffff16565b8982815181106127f657fe5b60209081029190910101526001016127b6565b5050505050505050919050565b6000821161286b576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156128b057600080fd5b505afa1580156128c4573d6000803e3d6000fd5b505050506040513d60208110156128da57600080fd5b5051905060006128e8612de4565b604154909150156129a3576000612905838363ffffffff61350a16565b9050604154670de0b6b3a7640000821161293657612931670de0b6b3a76400008363ffffffff61314316565b61294e565b61294e82670de0b6b3a764000063ffffffff61314316565b11156129a1576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a160606129e985612555565b905060005b603454811015612c7f57818181518110612a0457fe5b602002602001015160001415612a1957612c77565b600060348281548110612a2857fe5b60009182526020909120015483516001600160a01b039091169150839083908110612a4f57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612aad57600080fd5b505afa158015612ac1573d6000803e3d6000fd5b505050506040513d6020811015612ad757600080fd5b505110612b1457612b0f33848481518110612aee57fe5b6020026020010151836001600160a01b03166134949092919063ffffffff16565b612c75565b60006040600060348581548110612b2757fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612c34576000819050806001600160a01b031663d9caed123360348781548110612b7c57fe5b9060005260206000200160009054906101000a90046001600160a01b0316888881518110612ba657fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612c1657600080fd5b505af1158015612c2a573d6000803e3d6000fd5b5050505050612c73565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b6001016129ee565b508315612d2d576000805b8251811015612cd5576000612ca56034838154811061143157fe5b9050612cca612cbd8260120386858151811061275e57fe5b849063ffffffff61300b16565b925050600101612c8a565b5084811015612d2b576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612d8057600080fd5b505af1158015612d94573d6000803e3d6000fd5b50505050603b5485118015612db35750603754600160a01b900460ff16155b156122ba576122ba611a17565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b600061070c612df161342d565b612df961333d565b9063ffffffff61300b16565b6060612e0f610f3a565b604051908082528060200260200182016040528015612e38578160200160208202803883390190505b506037549091506001600160a01b031660005b60345481101561254e576060612e8160348381548110612e6757fe5b6000918252602090912001546001600160a01b03166117a4565b90508415612f8957612f6c600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612eea578181015183820152602001612ed2565b50505050905090810190601f168015612f175780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612f3457600080fd5b505afa158015612f48573d6000803e3d6000fd5b505050506040513d6020811015612f5e57600080fd5b50519063ffffffff61198f16565b848381518110612f7857fe5b602002602001018181525050613002565b60405163019af6bf60e41b8152602060048201818152835160248401528351612fe993600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612eea578181015183820152602001612ed2565b848381518110612ff557fe5b6020026020010181815250505b50600101612e4b565b600082820183811015613065576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906130a057508115155b949350505050565b6000826130b757506000610c48565b828202828482816130c457fe5b04146130655760405162461bcd60e51b81526004018080602001828103825260218152602001806138246021913960400191505060405180910390fd5b600061306583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613537565b600061306583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135d9565b613197826001600160a01b031661306c565b6131e8576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106132265780518252601f199092019160209182019101613207565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613288576040519150601f19603f3d011682016040523d82523d6000602084013e61328d565b606091505b5091509150816132e4576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611d985780806020019051602081101561330057600080fd5b5051611d985760405162461bcd60e51b815260040180806020018281038252602a815260200180613867602a913960400191505060405180910390fd5b6000805b6034548110156134295760006034828154811061335a57fe5b6000918252602082200154603480546001600160a01b039092169350613384918590811061143157fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156133d057600080fd5b505afa1580156133e4573d6000803e3d6000fd5b505050506040513d60208110156133fa57600080fd5b50519050801561341e5761341b6126d482601285900363ffffffff61198f16565b94505b505050600101613341565b5090565b6000805b603654811015613429576134756134686036838154811061344e57fe5b6000918252602090912001546001600160a01b0316613633565b839063ffffffff61300b16565b9150600101613431565b60006130658383670de0b6b3a76400006119e9565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d39908490613185565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061352584670de0b6b3a764000063ffffffff6130a816565b90506130a0818463ffffffff61310116565b600081836135c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613588578181015183820152602001613570565b50505050905090810190601f1680156135b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816135cf57fe5b0495945050505050565b6000818484111561362b5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613588578181015183820152602001613570565b505050900390565b600081815b60345481101561254e5760006136546034838154811061143157fe5b9050826001600160a01b031663aa388af66034848154811061367257fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156136c057600080fd5b505afa1580156136d4573d6000803e3d6000fd5b505050506040513d60208110156136ea57600080fd5b5051156137ad576000836001600160a01b0316635f5152266034858154811061370f57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561375d57600080fd5b505afa158015613771573d6000803e3d6000fd5b505050506040513d602081101561378757600080fd5b5051905080156137ab576137a86126d482601285900363ffffffff61198f16565b94505b505b5060010161363856fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45356e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e7472616374546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77466565206d757374206e6f742062652067726561746572207468616e207969656c645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a723158209a486e46973c6f28f9c4d92884e27d910324137adbdaefaaa0cbbf675447effe64736f6c634300050b00327bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a", + "deployedBytecode": "0x6080604052600436106101d85760003560e01c80637136a7a611610102578063af14052c11610095578063d4c3eea011610064578063d4c3eea0146105d0578063e6cc5432146105e5578063f0efb4c7146105fa578063fc0cfeee146106c9576101d8565b8063af14052c1461055e578063b888879e14610573578063c7af335214610588578063d38bfff41461059d576101d8565b80639fa1826e116100d15780639fa1826e146104ec578063a0aead4d14610501578063a403e4d514610516578063abaa991614610549576101d8565b80637136a7a61461044a5780637cbc2373146104745780638e510b52146104a45780639be918e6146104b9576101d8565b806331e19cfa1161017a578063570d8e1d11610149578063570d8e1d146103c35780635d36b190146103d85780635f515226146103ed57806367bd7ba314610420576101d8565b806331e19cfa1461035b57806349c1d54d1461037057806352d38e5d1461038557806353ca9f241461039a576101d8565b8063156e29f6116101b6578063156e29f61461028b5780631edfe3da146102cc578063207134b0146102e15780632acada4d146102f6576101d8565b806309f6442c1461021e5780630c340a2414610245578063128a8b0514610276575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610219573d6000f35b3d6000fd5b34801561022a57600080fd5b506102336106fc565b60408051918252519081900360200190f35b34801561025157600080fd5b5061025a610702565b604080516001600160a01b039092168252519081900360200190f35b34801561028257600080fd5b5061025a610711565b34801561029757600080fd5b506102ca600480360360608110156102ae57600080fd5b506001600160a01b038135169060208101359060400135610720565b005b3480156102d857600080fd5b50610233610b33565b3480156102ed57600080fd5b50610233610b39565b34801561030257600080fd5b5061030b610b3f565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561034757818101518382015260200161032f565b505050509050019250505060405180910390f35b34801561036757600080fd5b50610233610ba1565b34801561037c57600080fd5b5061025a610ba7565b34801561039157600080fd5b50610233610bb6565b3480156103a657600080fd5b506103af610bbc565b604080519115158252519081900360200190f35b3480156103cf57600080fd5b5061025a610bcc565b3480156103e457600080fd5b506102ca610bdb565b3480156103f957600080fd5b506102336004803603602081101561041057600080fd5b50356001600160a01b0316610c3d565b34801561042c57600080fd5b5061030b6004803603602081101561044357600080fd5b5035610c4e565b34801561045657600080fd5b506102ca6004803603602081101561046d57600080fd5b5035610c59565b34801561048057600080fd5b506102ca6004803603604081101561049757600080fd5b5080359060200135610e29565b3480156104b057600080fd5b50610233610f10565b3480156104c557600080fd5b506103af600480360360208110156104dc57600080fd5b50356001600160a01b0316610f16565b3480156104f857600080fd5b50610233610f34565b34801561050d57600080fd5b50610233610f3a565b34801561052257600080fd5b5061025a6004803603602081101561053957600080fd5b50356001600160a01b0316610f40565b34801561055557600080fd5b506102ca610f5b565b34801561056a57600080fd5b506102ca611016565b34801561057f57600080fd5b5061025a6110cb565b34801561059457600080fd5b506103af6110da565b3480156105a957600080fd5b506102ca600480360360208110156105c057600080fd5b50356001600160a01b03166110fd565b3480156105dc57600080fd5b506102336111a9565b3480156105f157600080fd5b506103af6111b3565b34801561060657600080fd5b506102ca6004803603606081101561061d57600080fd5b81019060208101813564010000000081111561063857600080fd5b82018360208201111561064a57600080fd5b8035906020019184602083028401116401000000008311171561066c57600080fd5b91939092909160208101903564010000000081111561068a57600080fd5b82018360208201111561069c57600080fd5b803590602001918460208302840111640100000000831117156106be57600080fd5b9193509150356111c3565b3480156106d557600080fd5b506102ca600480360360208110156106ec57600080fd5b50356001600160a01b03166116be565b60385481565b600061070c61177f565b905090565b603e546001600160a01b031681565b603754600160a81b900460ff1615610770576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156107c8576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff16610832576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610887576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf06108a4886117a4565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108f05781810151838201526020016108d8565b50505050905090810190601f16801561091d5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d602081101561096457600080fd5b505190506305f5e10081111561097b57506305f5e1005b6000610986876118d5565b9050600061099e87601284900363ffffffff61198f16565b905060006109c86109b685600a63ffffffff61198f16565b8990600a86900a63ffffffff6119e916565b90508615610a255786811015610a25576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a7c5750603754600160a01b900460ff16155b15610a8957610a89611a17565b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610adc57600080fd5b505af1158015610af0573d6000803e3d6000fd5b508b9250610b129150506001600160a01b03821633308c63ffffffff611d3e16565b603a548310610b2357610b23611d9e565b5050505050600182555050505050565b60395481565b60435481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b9757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b79575b5050505050905090565b60365490565b6042546001600160a01b031681565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610be36122c1565b6001600160a01b0316336001600160a01b031614610c325760405162461bcd60e51b81526004018080602001828103825260308152602001806138916030913960400191505060405180910390fd5b610c3b336122e6565b565b6000610c4882612394565b92915050565b6060610c4882612555565b603754600160a81b900460ff1615610ca9576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610d01576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d5357600080fd5b505afa158015610d67573d6000803e3d6000fd5b505050506040513d6020811015610d7d57600080fd5b5051118015610d965750603754600160a01b900460ff16155b15610da357610da3611a17565b603c54604080516370a0823160e01b81523360048201529051610e21926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610def57600080fd5b505afa158015610e03573d6000803e3d6000fd5b505050506040513d6020811015610e1957600080fd5b505184612816565b506001905550565b603754600160a81b900460ff1615610e79576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610ed1576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ef05750603754600160a01b900460ff16155b15610efd57610efd611a17565b610f078484612816565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610fab576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415611003576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611d9e565b5060019055565b603754600160a01b900460ff1615611067576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156110bf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611a17565b6037546001600160a01b031681565b60006110e461177f565b6001600160a01b0316336001600160a01b031614905090565b6111056110da565b611156576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61115f81612dc0565b806001600160a01b031661117161177f565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b600061070c612de4565b603754600160a81b900460ff1681565b603754600160a81b900460ff1615611213576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b78339815191528054600281141561126b576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282558584146112c3576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b60008060606112d182612e05565b905060005b8981101561150a57603360008c8c848181106112ee57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661135e576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061136c57fe5b90506020020135116113c5576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b60345481101561150157603481815481106113df57fe5b6000918252602090912001546001600160a01b03168c8c8481811061140057fe5b905060200201356001600160a01b03166001600160a01b031614156114f957600061144b6034838154811061143157fe5b6000918252602090912001546001600160a01b03166118d5565b9050600084838151811061145b57fe5b60200260200101519050670de0b6b3a76400008111156114805750670de0b6b3a76400005b6114b86114ab836012038e8e8881811061149657fe5b9050602002013561198f90919063ffffffff16565b889063ffffffff61300b16565b96506114f46114e78284600a0a8f8f898181106114d157fe5b905060200201356119e99092919063ffffffff16565b879063ffffffff61300b16565b955050505b6001016113c8565b506001016112d6565b5085156115665785821015611566576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b5483101580156115bd5750603754600160a01b900460ff16155b156115ca576115ca611a17565b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b15801561161d57600080fd5b505af1158015611631573d6000803e3d6000fd5b506000925050505b8981101561169c5760008b8b8381811061164f57fe5b905060200201356001600160a01b0316905061169333308c8c8681811061167257fe5b90506020020135846001600160a01b0316611d3e909392919063ffffffff16565b50600101611639565b50603a5483106116ae576116ae611d9e565b5050506001825550505050505050565b6116c66110da565b611717576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b6117208161306c565b61175b5760405162461bcd60e51b81526004018080602001828103825260248152602001806137d76024913960400191505060405180910390fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561181d57600080fd5b810190808051604051939291908464010000000082111561183d57600080fd5b90830190602082018581111561185257600080fd5b825164010000000081118282018810171561186c57600080fd5b82525081516020918201929091019080838360005b83811015611899578181015183820152602001611881565b50505050905090810190601f1680156118c65780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561191157600080fd5b505afa158015611925573d6000803e3d6000fd5b505050506040513d602081101561193b57600080fd5b505160ff16905060048110801590611954575060128111155b610c485760405162461bcd60e51b81526004018080602001828103825260298152602001806137fb6029913960400191505060405180910390fd5b6000808260000b13156119ba576119b383600084900b600a0a63ffffffff6130a816565b92506119e2565b60008260000b12156119e2576119df836000848103900b600a0a63ffffffff61310116565b92505b5090919050565b6000806119fc858563ffffffff6130a816565b9050611a0e818463ffffffff61310116565b95945050505050565b603754600160a01b900460ff1615611a68576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611aad57600080fd5b505afa158015611ac1573d6000803e3d6000fd5b505050506040513d6020811015611ad757600080fd5b5051905080611ae65750610c3b565b6000611af0612de4565b6042549091506001600160a01b03168015801590611b0d57508282115b15611c4f576000611b24838563ffffffff61314316565b90506000611b4f612710611b43604354856130a890919063ffffffff16565b9063ffffffff61310116565b9050808211611b8f5760405162461bcd60e51b81526004018080602001828103825260228152602001806138456022913960400191505060405180910390fd5b8015611c0357603c54604080516340c10f1960e01b81526001600160a01b03868116600483015260248201859052915191909216916340c10f1991604480830192600092919082900301818387803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b505050505b604080516001600160a01b03851681526020810184905280820183905290517f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809181900360600190a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9d57600080fd5b505afa158015611cb1573d6000803e3d6000fd5b505050506040513d6020811015611cc757600080fd5b5051925082821115611d3957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611d2057600080fd5b505af1158015611d34573d6000803e3d6000fd5b505050505b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611d98908590613185565b50505050565b6000611da861333d565b905080611db55750610c3b565b6000611dbf61342d565b90506000611dd3838363ffffffff61300b16565b9050600082611dff57603954611df890670de0b6b3a76400009063ffffffff61314316565b9050611e4b565b611e1884611b43846039546130a890919063ffffffff16565b905080670de0b6b3a76400001115611e4257611df8670de0b6b3a76400008263ffffffff61314316565b50505050610c3b565b80611e595750505050610c3b565b60005b603454811015611fe857600060348281548110611e7557fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611ec857600080fd5b505afa158015611edc573d6000803e3d6000fd5b505050506040513d6020811015611ef257600080fd5b5051905080611f02575050611fe0565b6000611f14828663ffffffff61347f16565b6001600160a01b03808516600090815260406020819052902054919250168015801590611f415750600082115b15611fdb5780611f616001600160a01b038616828563ffffffff61349416565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611fc157600080fd5b505af1158015611fd5573d6000803e3d6000fd5b50505050505b505050505b600101611e5c565b5060005b6036548110156122ba5760006036828154811061200557fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b15801561205257600080fd5b505afa158015612066573d6000803e3d6000fd5b505050506040513d602081101561207c57600080fd5b505190506001600160a01b038116156122b0576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b1580156120ca57600080fd5b505afa1580156120de573d6000803e3d6000fd5b505050506040513d60208110156120f457600080fd5b505190508061218357306001600160a01b0316630e5c011e6036868154811061211957fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561216657600080fd5b505af115801561217a573d6000803e3d6000fd5b505050506122ae565b60008290506000816001600160a01b03166370a08231603688815481106121a657fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156121f457600080fd5b505afa158015612208573d6000803e3d6000fd5b505050506040513d602081101561221e57600080fd5b505190508281106122ab57306001600160a01b0316630e5c011e6036888154811061224557fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561229257600080fd5b505af11580156122a6573d6000803e3d6000fd5b505050505b50505b505b5050600101611fec565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b038116612341576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661235361177f565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3612391816134e6565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b1580156123df57600080fd5b505afa1580156123f3573d6000803e3d6000fd5b505050506040513d602081101561240957600080fd5b5051915060005b60365481101561254e5760006036828154811061242957fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b15801561247f57600080fd5b505afa158015612493573d6000803e3d6000fd5b505050506040513d60208110156124a957600080fd5b50511561254557612542816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561250957600080fd5b505afa15801561251d573d6000803e3d6000fd5b505050506040513d602081101561253357600080fd5b5051859063ffffffff61300b16565b93505b50600101612410565b5050919050565b60606000612561610f3a565b9050606061256f6001612e05565b905060608260405190808252806020026020018201604052801561259d578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156125cc578160200160208202803883390190505b5060408051868152602080880282010190915290915060009081908680156125fe578160200160208202803883390190505b506038549097501561263d576000612627612710611b436038548c6130a890919063ffffffff16565b9050612639898263ffffffff61314316565b9850505b60005b6034548110156126ed5760006126766034838154811061265c57fe5b6000918252602090912001546001600160a01b0316612394565b9050600061268a6034848154811061143157fe5b90508187848151811061269957fe5b602002602001018181525050808684815181106126b257fe5b60209081029190910101526126e16126d483601284900363ffffffff61198f16565b869063ffffffff61300b16565b94505050600101612640565b5060005b60345481101561279e57600086828151811061270957fe5b60200260200101519050670de0b6b3a764000081101561272e5750670de0b6b3a76400005b600061278085611b43846127748a888151811061274757fe5b60200260200101516012038c898151811061275e57fe5b602002602001015161198f90919063ffffffff16565b9063ffffffff6130a816565b9050612792848263ffffffff61300b16565b935050506001016126f1565b5060006127b1898363ffffffff61350a16565b905060005b603454811015612809576127ea84611b43848985815181106127d457fe5b60200260200101516130a890919063ffffffff16565b8982815181106127f657fe5b60209081029190910101526001016127b6565b5050505050505050919050565b6000821161286b576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156128b057600080fd5b505afa1580156128c4573d6000803e3d6000fd5b505050506040513d60208110156128da57600080fd5b5051905060006128e8612de4565b604154909150156129a3576000612905838363ffffffff61350a16565b9050604154670de0b6b3a7640000821161293657612931670de0b6b3a76400008363ffffffff61314316565b61294e565b61294e82670de0b6b3a764000063ffffffff61314316565b11156129a1576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a160606129e985612555565b905060005b603454811015612c7f57818181518110612a0457fe5b602002602001015160001415612a1957612c77565b600060348281548110612a2857fe5b60009182526020909120015483516001600160a01b039091169150839083908110612a4f57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612aad57600080fd5b505afa158015612ac1573d6000803e3d6000fd5b505050506040513d6020811015612ad757600080fd5b505110612b1457612b0f33848481518110612aee57fe5b6020026020010151836001600160a01b03166134949092919063ffffffff16565b612c75565b60006040600060348581548110612b2757fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612c34576000819050806001600160a01b031663d9caed123360348781548110612b7c57fe5b9060005260206000200160009054906101000a90046001600160a01b0316888881518110612ba657fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612c1657600080fd5b505af1158015612c2a573d6000803e3d6000fd5b5050505050612c73565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b6001016129ee565b508315612d2d576000805b8251811015612cd5576000612ca56034838154811061143157fe5b9050612cca612cbd8260120386858151811061275e57fe5b849063ffffffff61300b16565b925050600101612c8a565b5084811015612d2b576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612d8057600080fd5b505af1158015612d94573d6000803e3d6000fd5b50505050603b5485118015612db35750603754600160a01b900460ff16155b156122ba576122ba611a17565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b600061070c612df161342d565b612df961333d565b9063ffffffff61300b16565b6060612e0f610f3a565b604051908082528060200260200182016040528015612e38578160200160208202803883390190505b506037549091506001600160a01b031660005b60345481101561254e576060612e8160348381548110612e6757fe5b6000918252602090912001546001600160a01b03166117a4565b90508415612f8957612f6c600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612eea578181015183820152602001612ed2565b50505050905090810190601f168015612f175780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612f3457600080fd5b505afa158015612f48573d6000803e3d6000fd5b505050506040513d6020811015612f5e57600080fd5b50519063ffffffff61198f16565b848381518110612f7857fe5b602002602001018181525050613002565b60405163019af6bf60e41b8152602060048201818152835160248401528351612fe993600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612eea578181015183820152602001612ed2565b848381518110612ff557fe5b6020026020010181815250505b50600101612e4b565b600082820183811015613065576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906130a057508115155b949350505050565b6000826130b757506000610c48565b828202828482816130c457fe5b04146130655760405162461bcd60e51b81526004018080602001828103825260218152602001806138246021913960400191505060405180910390fd5b600061306583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613537565b600061306583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135d9565b613197826001600160a01b031661306c565b6131e8576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106132265780518252601f199092019160209182019101613207565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613288576040519150601f19603f3d011682016040523d82523d6000602084013e61328d565b606091505b5091509150816132e4576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611d985780806020019051602081101561330057600080fd5b5051611d985760405162461bcd60e51b815260040180806020018281038252602a815260200180613867602a913960400191505060405180910390fd5b6000805b6034548110156134295760006034828154811061335a57fe5b6000918252602082200154603480546001600160a01b039092169350613384918590811061143157fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156133d057600080fd5b505afa1580156133e4573d6000803e3d6000fd5b505050506040513d60208110156133fa57600080fd5b50519050801561341e5761341b6126d482601285900363ffffffff61198f16565b94505b505050600101613341565b5090565b6000805b603654811015613429576134756134686036838154811061344e57fe5b6000918252602090912001546001600160a01b0316613633565b839063ffffffff61300b16565b9150600101613431565b60006130658383670de0b6b3a76400006119e9565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d39908490613185565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061352584670de0b6b3a764000063ffffffff6130a816565b90506130a0818463ffffffff61310116565b600081836135c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613588578181015183820152602001613570565b50505050905090810190601f1680156135b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816135cf57fe5b0495945050505050565b6000818484111561362b5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613588578181015183820152602001613570565b505050900390565b600081815b60345481101561254e5760006136546034838154811061143157fe5b9050826001600160a01b031663aa388af66034848154811061367257fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156136c057600080fd5b505afa1580156136d4573d6000803e3d6000fd5b505050506040513d60208110156136ea57600080fd5b5051156137ad576000836001600160a01b0316635f5152266034858154811061370f57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561375d57600080fd5b505afa158015613771573d6000803e3d6000fd5b505050506040513d602081101561378757600080fd5b5051905080156137ab576137a86126d482601285900363ffffffff61198f16565b94505b505b5060010161363856fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45356e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e7472616374546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77466565206d757374206e6f742062652067726561746572207468616e207969656c645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a723158209a486e46973c6f28f9c4d92884e27d910324137adbdaefaaa0cbbf675447effe64736f6c634300050b0032", "devdoc": { "methods": { "allocate()": { @@ -823,8 +898,7 @@ } }, "rebase()": { - "details": "Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD.", - "return": "uint256 New total supply of OUSD" + "details": "Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD." }, "redeem(uint256,uint256)": { "details": "Withdraw a supported asset and burn OUSD.", @@ -841,7 +915,7 @@ "setAdminImpl(address)": { "details": "set the implementation for the admin, this needs to be in a base class else we cannot set it", "params": { - "newImpl": "address pf the implementation" + "newImpl": "address of the implementation" } }, "totalValue()": { diff --git a/contracts/deployments/rinkeby/.migrations.json b/contracts/deployments/rinkeby/.migrations.json index d1fca3e21f..c10a6f0487 100644 --- a/contracts/deployments/rinkeby/.migrations.json +++ b/contracts/deployments/rinkeby/.migrations.json @@ -10,5 +10,6 @@ "010_upgrade_single_asset_staking": 1609968697, "011_ousd_fix": 1610146101, "005_compensation_claims": 1612291029, - "012_upgrades": 1612292067 + "012_upgrades": 1612292067, + "013_trustee": 1612380511 } \ No newline at end of file diff --git a/contracts/deployments/rinkeby/VaultCore.json b/contracts/deployments/rinkeby/VaultCore.json index dc367e49ba..4fd6550a85 100644 --- a/contracts/deployments/rinkeby/VaultCore.json +++ b/contracts/deployments/rinkeby/VaultCore.json @@ -1,5 +1,5 @@ { - "address": "0x1376fE696858E0163a886eBcFCf3f5eB24BC9ac4", + "address": "0x1D6B56e17D08e83dc2198A61Cb5BC9744cF8D9fE", "abi": [ { "constant": true, @@ -86,6 +86,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeFeeBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -116,6 +131,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -347,13 +377,7 @@ "constant": false, "inputs": [], "name": "rebase", - "outputs": [ - { - "internalType": "uint256", - "name": "newTotalSupply", - "type": "uint256" - } - ], + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -702,6 +726,57 @@ "name": "MaxSupplyDiffChanged", "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" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_basis", + "type": "uint256" + } + ], + "name": "TrusteeFeeBpsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "TrusteeAddressChanged", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -741,42 +816,42 @@ "type": "event" } ], - "transactionHash": "0xca8a58d945608194f537d520dd870796294800ae58e5a959e9482bb35f71a631", + "transactionHash": "0x91ffd8a6befc2eaffcb917d3f38580d3601d3bcc6851f3890b00664bca3d1330", "receipt": { "to": null, "from": "0xD85A569F3C26f81070544451131c742283360400", - "contractAddress": "0x1376fE696858E0163a886eBcFCf3f5eB24BC9ac4", - "transactionIndex": 12, - "gasUsed": "3139150", - "logsBloom": "0x00000000400000000000800000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000004000000000000000000000100000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000020000000000000000000000000000000000000000400000000000000000000000000", - "blockHash": "0x8d0f2467a247f23efb110ac5ae80a68d48fb30b6f9157fa5d451260595978ce1", - "transactionHash": "0xca8a58d945608194f537d520dd870796294800ae58e5a959e9482bb35f71a631", + "contractAddress": "0x1D6B56e17D08e83dc2198A61Cb5BC9744cF8D9fE", + "transactionIndex": 2, + "gasUsed": "3252626", + "logsBloom": "0x00000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000020000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000010020000000000000000000000000000000000000000400000000000000000000000000", + "blockHash": "0x2b49d1234233b21cfeede6faf85357fc942ce5d110f6ed167388b502415323aa", + "transactionHash": "0x91ffd8a6befc2eaffcb917d3f38580d3601d3bcc6851f3890b00664bca3d1330", "logs": [ { - "transactionIndex": 12, - "blockNumber": 7803488, - "transactionHash": "0xca8a58d945608194f537d520dd870796294800ae58e5a959e9482bb35f71a631", - "address": "0x1376fE696858E0163a886eBcFCf3f5eB24BC9ac4", + "transactionIndex": 2, + "blockNumber": 8010137, + "transactionHash": "0x91ffd8a6befc2eaffcb917d3f38580d3601d3bcc6851f3890b00664bca3d1330", + "address": "0x1D6B56e17D08e83dc2198A61Cb5BC9744cF8D9fE", "topics": [ "0xc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000d85a569f3c26f81070544451131c742283360400" ], "data": "0x", - "logIndex": 22, - "blockHash": "0x8d0f2467a247f23efb110ac5ae80a68d48fb30b6f9157fa5d451260595978ce1" + "logIndex": 1, + "blockHash": "0x2b49d1234233b21cfeede6faf85357fc942ce5d110f6ed167388b502415323aa" } ], - "blockNumber": 7803488, - "cumulativeGasUsed": "4709298", + "blockNumber": 8010137, + "cumulativeGasUsed": "7391009", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "d641aaf0ed5d604d73e8f53c6d96978e", - "metadata": "{\"compiler\":{\"version\":\"0.5.11+commit.22be8592.mod\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"redeemFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"uniswapAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaultBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllAssets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getStrategyCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebaseThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebasePaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"strategistAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"claimGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"checkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedeemOutputs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeemAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxSupplyDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"isSupportedAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoAllocateThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAssetCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetDefaultStrategies\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"allocate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rebase\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTotalSupply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"priceProvider\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isGovernor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"transferGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"capitalPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_assets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mintMultiple\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImpl\",\"type\":\"address\"}],\"name\":\"setAdminImpl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"AssetSupported\",\"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\":\"_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\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"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\":[],\"name\":\"CapitalPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebasePaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebaseUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vaultBuffer\",\"type\":\"uint256\"}],\"name\":\"VaultBufferUpdated\",\"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\":\"_priceProvider\",\"type\":\"address\"}],\"name\":\"PriceProviderUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"AllocateThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"RebaseThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"UniswapUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"StrategistUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupplyDiff\",\"type\":\"uint256\"}],\"name\":\"MaxSupplyDiffChanged\",\"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\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"GovernorshipTransferred\",\"type\":\"event\"}],\"devdoc\":{\"methods\":{\"allocate()\":{\"details\":\"Allocate unallocated funds on Vault to strategies.*\"},\"checkBalance(address)\":{\"params\":{\"_asset\":\"Address of asset\"},\"return\":\"uint256 Balance of asset in decimals of asset\"},\"claimGovernance()\":{\"details\":\"Claim Governance of the contract to a new account (`newGovernor`). Can only be called by the new Governor.\"},\"getAllAssets()\":{\"details\":\"Return all asset addresses in order\"},\"getAssetCount()\":{\"details\":\"Return the number of assets suppported by the Vault.\"},\"getStrategyCount()\":{\"details\":\"Return the number of strategies active on the Vault.\"},\"governor()\":{\"details\":\"Returns the address of the current Governor.\"},\"isGovernor()\":{\"details\":\"Returns true if the caller is the current Governor.\"},\"mint(address,uint256,uint256)\":{\"details\":\"Deposit a supported asset and mint OUSD.\",\"params\":{\"_amount\":\"Amount of the asset being deposited\",\"_asset\":\"Address of the asset being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"mintMultiple(address[],uint256[],uint256)\":{\"details\":\"Mint for multiple assets in the same call.\",\"params\":{\"_amounts\":\"Amount of each asset at the same index in the _assets to deposit.\",\"_assets\":\"Addresses of assets being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"rebase()\":{\"details\":\"Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD.\",\"return\":\"uint256 New total supply of OUSD\"},\"redeem(uint256,uint256)\":{\"details\":\"Withdraw a supported asset and burn OUSD.\",\"params\":{\"_amount\":\"Amount of OUSD to burn\",\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"redeemAll(uint256)\":{\"params\":{\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"setAdminImpl(address)\":{\"details\":\"set the implementation for the admin, this needs to be in a base class else we cannot set it\",\"params\":{\"newImpl\":\"address pf the implementation\"}},\"totalValue()\":{\"details\":\"Determine the total value of assets held by the vault and its strategies.\",\"return\":\"uint256 value Total value in USD (1e18)\"},\"transferGovernance(address)\":{\"details\":\"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\",\"params\":{\"_newGovernor\":\"Address of the new Governor\"}}}},\"userdoc\":{\"methods\":{\"allocate()\":{\"notice\":\"Allocate unallocated funds on Vault to strategies.\"},\"calculateRedeemOutputs(uint256)\":{\"notice\":\"Calculate the outputs for a redeem function, i.e. the mix of coins that will be returned\"},\"checkBalance(address)\":{\"notice\":\"Get the balance of an asset held in Vault and all strategies.\"},\"redeemAll(uint256)\":{\"notice\":\"Withdraw a supported asset and burn all OUSD.\"}}}},\"settings\":{\"compilationTarget\":{\"contracts/vault/VaultCore.sol\":\"VaultCore\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x640b6dee7a4b830bdfd52b5031a07fc2b12209f5b2e29e5d364a7d37f69d8076\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\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(address sender, address recipient, uint256 amount) 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\":\"0xe5bb0f57cff3e299f360052ba50f1ea0fff046df2be070b6943e0e3c3fdad8a9\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6f2c9955d65c522b80f4b8792f076512d2df947d2112cbc4d98a4781ed42ede2\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\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 * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1a8e5072509c5ea7365eb1d48030b9be865140c8fb779968da0a459a0e174a11\"},\"@openzeppelin/upgrades/contracts/Initializable.sol\":{\"content\":\"pragma solidity >=0.4.24 <0.7.0;\\n\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\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 use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || isConstructor() || !initialized, \\\"Contract instance has already been initialized\\\");\\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 /// @dev Returns true if and only if the function is running in the constructor\\n function isConstructor() private view returns (bool) {\\n // extcodesize checks the size of the code stored in an address, and\\n // address returns the current address. Since the code is still not\\n // deployed when running a constructor, any checks on its code size will\\n // yield zero, making it an effective way to detect if a contract is\\n // under construction or not.\\n address self = address(this);\\n uint256 cs;\\n assembly { cs := extcodesize(self) }\\n return cs == 0;\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0x9bfec92e36234ecc99b5d37230acb6cd1f99560233753162204104a4897e8721\"},\"contracts/governance/Governable.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Governable Contract\\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\\n private constant governorPosition = 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\\n\\n // keccak256(\\\"OUSD.pending.governor\\\");\\n bytes32\\n private constant pendingGovernorPosition = 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\\n\\n // keccak256(\\\"OUSD.reentry.status\\\");\\n bytes32\\n private constant reentryStatusPosition = 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() internal {\\n _setGovernor(msg.sender);\\n emit GovernorshipTransferred(address(0), _governor());\\n }\\n\\n /**\\n * @dev 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 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 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 * @dev 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 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 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 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 assembly {\\n sstore(position, _NOT_ENTERED)\\n }\\n }\\n\\n function _setPendingGovernor(address newGovernor) internal {\\n bytes32 position = pendingGovernorPosition;\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0x3e51ea48102945bf4b305bf9722a07514a585a29555d92f8c84352d1a4cfcee1\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x01eab42b6d54fa5389598e0663c24680ecc017e2da848e8ea1c40aeaa8225eef\"},\"contracts/interfaces/IMinMaxOracle.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IMinMaxOracle {\\n //Assuming 8 decimals\\n function priceMin(string calldata symbol) external view returns (uint256);\\n\\n function priceMax(string calldata symbol) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x164c8759ca5a8e39bbe1de6b2504098c543b2f15663c9d452e083418f8313f48\"},\"contracts/interfaces/IStrategy.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 Lending 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 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 collectRewardToken() external;\\n\\n /**\\n * @dev The address of the reward token for the Strategy.\\n */\\n function rewardTokenAddress() external pure returns (address);\\n\\n /**\\n * @dev The threshold (denominated in the reward token) over which the\\n * vault will auto harvest on allocate calls.\\n */\\n function rewardLiquidationThreshold() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9ef9546d60635c630e3446f270bc93f34593f5c77db8c671146f6c1eb0b2774\"},\"contracts/interfaces/IVault.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IVault {\\n event AssetSupported(address _asset);\\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 DepositsPaused();\\n event DepositsUnpaused();\\n\\n // Governable.sol\\n function transferGovernance(address _newGovernor) external;\\n\\n function claimGovernance() external;\\n\\n function governor() external view returns (address);\\n\\n // VaultAdmin.sol\\n function setPriceProvider(address _priceProvider) external;\\n\\n function priceProvider() external view returns (address);\\n\\n function setRedeemFeeBps(uint256 _redeemFeeBps) external;\\n\\n function redeemFeeBps() external view returns (uint256);\\n\\n function setVaultBuffer(uint256 _vaultBuffer) external;\\n\\n function vaultBuffer() external view returns (uint256);\\n\\n function setAutoAllocateThreshold(uint256 _threshold) external;\\n\\n function autoAllocateThreshold() external view returns (uint256);\\n\\n function setRebaseThreshold(uint256 _threshold) external;\\n\\n function rebaseThreshold() external view returns (uint256);\\n\\n function setStrategistAddr(address _address) external;\\n\\n function strategistAddr() external view returns (address);\\n\\n function setUniswapAddr(address _address) external;\\n\\n function uniswapAddr() external view returns (address);\\n\\n function supportAsset(address _asset) external;\\n\\n function approveStrategy(address _addr) external;\\n\\n function removeStrategy(address _addr) external;\\n\\n function setAssetDefaultStrategy(address _asset, address _strategy)\\n external;\\n\\n function assetDefaultStrategies(address _asset)\\n external\\n view\\n returns (address);\\n\\n function pauseRebase() external;\\n\\n function unpauseRebase() external;\\n\\n function rebasePaused() external view returns (bool);\\n\\n function pauseCapital() external;\\n\\n function unpauseCapital() external;\\n\\n function capitalPaused() external view returns (bool);\\n\\n function transferToken(address _asset, uint256 _amount) external;\\n\\n function harvest() external;\\n\\n function harvest(address _strategyAddr) external;\\n\\n function priceUSDMint(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n function priceUSDRedeem(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n // VaultCore.sol\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount) external;\\n\\n function redeemAll(uint256 _minimumUnitAmount) external;\\n\\n function allocate() external;\\n\\n function reallocate(\\n address _strategyFromAddress,\\n address _strategyToAddress,\\n address[] calldata _assets,\\n uint256[] calldata _amounts\\n ) external;\\n\\n function rebase() external returns (uint256);\\n\\n function totalValue() external view returns (uint256 value);\\n\\n function checkBalance() external view returns (uint256);\\n\\n function checkBalance(address _asset) external view returns (uint256);\\n\\n function calculateRedeemOutputs(uint256 _amount)\\n external\\n view\\n returns (uint256[] memory);\\n\\n function getAssetCount() external view returns (uint256);\\n\\n function getAllAssets() external view returns (address[] memory);\\n\\n function getStrategyCount() external view returns (uint256);\\n\\n function isSupportedAsset(address _asset) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x2a5958a8d9e0c878b5d62578e03aa9c39a7f1803ff7e308074ada326a9d45518\"},\"contracts/token/OUSD.sol\":{\"content\":\"pragma solidity 0.5.11;\\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/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport {\\n InitializableERC20Detailed\\n} 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 TotalSupplyUpdated(\\n uint256 totalSupply,\\n uint256 rebasingCredits,\\n uint256 rebasingCreditsPerToken\\n );\\n\\n // MAX_SUPPLY is chosen to guarantee applied changes to _totalSupply in\\n // changeSupply(_newTotalSupply) deviate from the value provided in\\n // _newTotalSupply by < 1\\n uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1\\n\\n uint256 public _totalSupply;\\n uint256 public rebasingCredits;\\n // Exchange rate between internal credits and OUSD\\n uint256 public rebasingCreditsPerToken;\\n\\n mapping(address => uint256) private _deprecated_creditBalances;\\n\\n // Allowances denominated in OUSD\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n address public vaultAddress = address(0);\\n\\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 _deprecated_nonRebasingCredits;\\n uint256 public nonRebasingSupply;\\n mapping(address => uint256) public nonRebasingCreditsPerToken;\\n enum RebaseOptions { NotSet, OptOut, OptIn }\\n mapping(address => RebaseOptions) public rebaseState;\\n\\n mapping(address => uint256) private _creditBalances;\\n\\n function initialize(\\n string calldata _nameArg,\\n string calldata _symbolArg,\\n address _vaultAddress\\n ) external onlyGovernor initializer {\\n InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);\\n rebasingCreditsPerToken = 1e18;\\n vaultAddress = _vaultAddress;\\n }\\n\\n /**\\n * @dev Verifies that the caller is the Savings Manager 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 returns (uint256) {\\n return _totalSupply;\\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) public view returns (uint256) {\\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 * @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 return (_creditBalances[_account], _creditsPerToken(_account));\\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) public returns (bool) {\\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 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 an owner has allowed to a _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 returns (uint256)\\n {\\n return _allowances[_owner][_spender];\\n }\\n\\n /**\\n * @dev Approve the passed address to spend the specified _amount of tokens on behalf of\\n * msg.sender. This method is included for ERC20 compatibility.\\n * increaseAllowance and decreaseAllowance should be used instead.\\n * Changing an allowance with this method brings the risk that someone may transfer both\\n * the old and the new allowance - if they are both greater than zero - if a transfer\\n * transaction is mined before the later approve() call is mined.\\n *\\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) public returns (bool) {\\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 a _spender.\\n * This method should be used instead of approve() to avoid the double approval vulnerability\\n * 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 a _spender.\\n * @param _spender The address which will spend the funds.\\n * @param _subtractedValue The _amount of tokens to decrease the allowance 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 return _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 return _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\\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 accounts balance non rebasing, i.e. does not alter with rebases\\n * @param _account Address of the account.\\n */\\n function _isNonRebasingAccount(address _account) internal returns (bool) {\\n if (Address.isContract(_account)) {\\n // Contracts by default opt out\\n if (rebaseState[_account] == RebaseOptions.OptIn) {\\n // If they've opted in explicitly it is not a non rebasing\\n // address\\n return false;\\n }\\n // Is a non rebasing account because no explicit opt in\\n // Make sure the rebasing/non-rebasing supply is updated and\\n // fixed credits per token is set for this account\\n _ensureRebasingMigration(_account);\\n return true;\\n } else {\\n // EOAs by default opt in\\n // Check for explicit opt out\\n return rebaseState[_account] == RebaseOptions.OptOut;\\n }\\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 // 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(_creditBalances[_account]);\\n }\\n }\\n\\n /**\\n * @dev Add a contract address to the non rebasing exception list. I.e. the\\n * address's balance will be part of rebases so the account will be exposed\\n * to upside and downside.\\n */\\n function rebaseOptIn() public nonReentrant {\\n require(_isNonRebasingAccount(msg.sender), \\\"Account has not opted out\\\");\\n\\n // Convert balance into the same amount at the current exchange rate\\n uint256 newCreditBalance = _creditBalances[msg.sender]\\n .mul(rebasingCreditsPerToken)\\n .div(_creditsPerToken(msg.sender));\\n\\n // Decreasing non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.sub(balanceOf(msg.sender));\\n\\n _creditBalances[msg.sender] = newCreditBalance;\\n\\n // Increase rebasing credits, totalSupply remains unchanged so no\\n // adjustment necessary\\n rebasingCredits = rebasingCredits.add(_creditBalances[msg.sender]);\\n\\n rebaseState[msg.sender] = RebaseOptions.OptIn;\\n\\n // Delete any fixed credits per token\\n delete nonRebasingCreditsPerToken[msg.sender];\\n }\\n\\n /**\\n * @dev Remove a contract address to the non rebasing exception list.\\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 }\\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 * @return uint256 representing the new total supply.\\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 TotalSupplyUpdated(\\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 TotalSupplyUpdated(\\n _totalSupply,\\n rebasingCredits,\\n rebasingCreditsPerToken\\n );\\n }\\n}\\n\",\"keccak256\":\"0x18d15a386750d93a6252becc33d8df577a397c0ea44135a7208ce33bb65233c6\"},\"contracts/utils/Helpers.sol\":{\"content\":\"pragma solidity 0.5.11;\\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\":\"0xd2ca92e0af883dc1aec5b22caced274e59829e0e30a9e955dcc48b8d921f5cdc\"},\"contracts/utils/InitializableERC20Detailed.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 */\\ncontract InitializableERC20Detailed is IERC20 {\\n // Ignore these, they are present to align storage slots correctly after\\n // upgrade\\n mapping(address => uint256) private __gap1;\\n mapping(address => mapping(address => uint256)) private __gap2;\\n uint256 private constant __gap3 = 0;\\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 * @dev Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0xdb555620ce66bb4a07890e352683b0e6777fb06585935e5ce3ab80e6282c96ce\"},\"contracts/utils/StableMath.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/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 adjustment Amount to adjust by e.g. scaleBy(1e18, -1) == 1e17\\n */\\n function scaleBy(uint256 x, int8 adjustment)\\n internal\\n pure\\n returns (uint256)\\n {\\n if (adjustment > 0) {\\n x = x.mul(10**uint256(adjustment));\\n } else if (adjustment < 0) {\\n x = x.div(10**uint256(adjustment * -1));\\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 9e38 / 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\":\"0xa77fccf850feb6d54ba3a6530f92554caef8a67a1ceb573d4f8a5d1bf64ff9d2\"},\"contracts/vault/VaultCore.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Vault Contract\\n * @notice The Vault contract stores assets. On a deposit, OUSD will be minted\\n and sent to the depositor. On a withdrawal, OUSD will be burned and\\n assets will be sent to the withdrawer. The Vault accepts deposits of\\n interest form yield bearing strategies which will modify the supply\\n of OUSD.\\n * @author Origin Protocol Inc\\n */\\n\\nimport \\\"./VaultStorage.sol\\\";\\nimport { IMinMaxOracle } from \\\"../interfaces/IMinMaxOracle.sol\\\";\\nimport { IVault } from \\\"../interfaces/IVault.sol\\\";\\n\\ncontract VaultCore is VaultStorage {\\n uint256 constant MAX_UINT = 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 /**\\n * @dev Deposit a supported asset and mint OUSD.\\n * @param _asset Address of the asset being deposited\\n * @param _amount Amount of the asset being deposited\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(assets[_asset].isSupported, \\\"Asset is not supported\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 price = IMinMaxOracle(priceProvider).priceMin(\\n Helpers.getSymbol(_asset)\\n );\\n if (price > 1e8) {\\n price = 1e8;\\n }\\n uint256 assetDecimals = Helpers.getDecimals(_asset);\\n uint256 unitAdjustedDeposit = _amount.scaleBy(int8(18 - assetDecimals));\\n uint256 priceAdjustedDeposit = _amount.mulTruncateScale(\\n price.scaleBy(int8(10)), // 18-8 because oracles have 8 decimals precision\\n 10**assetDecimals\\n );\\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 (unitAdjustedDeposit >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n // Mint matching OUSD\\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 (unitAdjustedDeposit >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Mint for multiple assets in the same call.\\n * @param _assets Addresses of assets being deposited\\n * @param _amounts Amount of each asset at the same index in the _assets\\n * to deposit.\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amounts,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(_assets.length == _amounts.length, \\\"Parameter length mismatch\\\");\\n\\n uint256 unitAdjustedTotal = 0;\\n uint256 priceAdjustedTotal = 0;\\n uint256[] memory assetPrices = _getAssetPrices(false);\\n for (uint256 j = 0; j < _assets.length; j++) {\\n // In memoriam\\n require(assets[_assets[j]].isSupported, \\\"Asset is not supported\\\");\\n require(_amounts[j] > 0, \\\"Amount must be greater than 0\\\");\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (_assets[j] == allAssets[i]) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n uint256 price = assetPrices[i];\\n if (price > 1e18) {\\n price = 1e18;\\n }\\n unitAdjustedTotal = unitAdjustedTotal.add(\\n _amounts[j].scaleBy(int8(18 - assetDecimals))\\n );\\n priceAdjustedTotal = priceAdjustedTotal.add(\\n _amounts[j].mulTruncateScale(price, 10**assetDecimals)\\n );\\n }\\n }\\n }\\n\\n if (_minimumOusdAmount > 0) {\\n require(\\n priceAdjustedTotal >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n }\\n\\n emit Mint(msg.sender, priceAdjustedTotal);\\n\\n // Rebase must happen before any transfers occur.\\n if (unitAdjustedTotal >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n oUSD.mint(msg.sender, priceAdjustedTotal);\\n\\n for (uint256 i = 0; i < _assets.length; i++) {\\n IERC20 asset = IERC20(_assets[i]);\\n asset.safeTransferFrom(msg.sender, address(this), _amounts[i]);\\n }\\n\\n if (unitAdjustedTotal >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n public\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(_amount, _minimumUnitAmount);\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount) internal {\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 _totalSupply = oUSD.totalSupply();\\n uint256 _backingValue = _totalValue();\\n\\n if (maxSupplyDiff > 0) {\\n // Allow a max difference of maxSupplyDiff% between\\n // backing assets value and OUSD total supply\\n uint256 diff = _totalSupply.divPrecisely(_backingValue);\\n\\n require(\\n (diff > 1e18 ? diff.sub(1e18) : uint256(1e18).sub(diff)) <=\\n maxSupplyDiff,\\n \\\"Backing supply liquidity error\\\"\\n );\\n }\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // Calculate redemption outputs\\n uint256[] memory outputs = _calculateRedeemOutputs(_amount);\\n // Send outputs\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (outputs[i] == 0) continue;\\n\\n IERC20 asset = IERC20(allAssets[i]);\\n\\n if (asset.balanceOf(address(this)) >= outputs[i]) {\\n // Use Vault funds first if sufficient\\n asset.safeTransfer(msg.sender, outputs[i]);\\n } else {\\n address strategyAddr = assetDefaultStrategies[allAssets[i]];\\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, allAssets[i], 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 uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n unitTotal = unitTotal.add(\\n outputs[i].scaleBy(int8(18 - assetDecimals))\\n );\\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 if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn all OUSD.\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeemAll(uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n // Unfortunately we have to do balanceOf twice, the rebase may change\\n // the account balance\\n if (oUSD.balanceOf(msg.sender) > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\n * @dev Allocate unallocated funds on Vault to strategies.\\n **/\\n function allocate() public whenNotCapitalPaused nonReentrant {\\n _allocate();\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\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.add(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).sub(vaultBuffer);\\n } else {\\n vaultBufferModifier = vaultBuffer.mul(calculatedTotalValue).div(\\n vaultValue\\n );\\n if (1e18 > vaultBufferModifier) {\\n // E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17\\n // (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault\\n vaultBufferModifier = uint256(1e18).sub(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 the the appropriate\\n // strategy\\n for (uint256 i = 0; i < allAssets.length; 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[address(\\n 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 }\\n }\\n\\n // Harvest for all reward tokens above reward liquidation threshold\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n address rewardTokenAddress = strategy.rewardTokenAddress();\\n if (rewardTokenAddress != address(0)) {\\n uint256 liquidationThreshold = strategy\\n .rewardLiquidationThreshold();\\n if (liquidationThreshold == 0) {\\n // No threshold set, always harvest from strategy\\n IVault(address(this)).harvest(allStrategies[i]);\\n } else {\\n // Check balance against liquidation threshold\\n // Note some strategies don't hold the reward token balance\\n // on their contract so the liquidation threshold should be\\n // set to 0\\n IERC20 rewardToken = IERC20(rewardTokenAddress);\\n uint256 rewardTokenAmount = rewardToken.balanceOf(\\n allStrategies[i]\\n );\\n if (rewardTokenAmount >= liquidationThreshold) {\\n IVault(address(this)).harvest(allStrategies[i]);\\n }\\n }\\n }\\n }\\n }\\n\\n /**\\n * @dev Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OUSD.\\n * @return uint256 New total supply of OUSD\\n */\\n function rebase()\\n public\\n whenNotRebasePaused\\n nonReentrant\\n returns (uint256 newTotalSupply)\\n {\\n return _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 OUSD.\\n * @return uint256 New total supply of OUSD\\n */\\n function _rebase()\\n internal\\n whenNotRebasePaused\\n returns (uint256 newTotalSupply)\\n {\\n if (oUSD.totalSupply() == 0) return 0;\\n uint256 oldTotalSupply = oUSD.totalSupply();\\n newTotalSupply = _totalValue();\\n // Only rachet upwards\\n if (newTotalSupply > oldTotalSupply) {\\n oUSD.changeSupply(newTotalSupply);\\n }\\n }\\n\\n /**\\n * @dev Determine the total value of assets held by the vault and its\\n * strategies.\\n * @return uint256 value Total value in USD (1e18)\\n */\\n function totalValue() external view 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 uint256 value Total value in USD (1e18)\\n */\\n function _totalValue() internal view returns (uint256 value) {\\n return _totalValueInVault().add(_totalValueInStrategies());\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Vault.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInVault() internal view returns (uint256 value) {\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n IERC20 asset = IERC20(allAssets[y]);\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n uint256 balance = asset.balanceOf(address(this));\\n if (balance > 0) {\\n value = value.add(balance.scaleBy(int8(18 - assetDecimals)));\\n }\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Strategies.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategies() internal view returns (uint256 value) {\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n value = value.add(_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 uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategy(address _strategyAddr)\\n internal\\n view\\n returns (uint256 value)\\n {\\n IStrategy strategy = IStrategy(_strategyAddr);\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n if (strategy.supportsAsset(allAssets[y])) {\\n uint256 balance = strategy.checkBalance(allAssets[y]);\\n if (balance > 0) {\\n value = value.add(\\n balance.scaleBy(int8(18 - assetDecimals))\\n );\\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 uint256 Balance of asset in decimals of asset\\n */\\n function _checkBalance(address _asset)\\n internal\\n view\\n returns (uint256 balance)\\n {\\n IERC20 asset = IERC20(_asset);\\n balance = asset.balanceOf(address(this));\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n if (strategy.supportsAsset(_asset)) {\\n balance = balance.add(strategy.checkBalance(_asset));\\n }\\n }\\n }\\n\\n /**\\n * @notice Get the balance of all assets held in Vault and all strategies.\\n * @return uint256 Balance of all assets (1e18)\\n */\\n function _checkBalance() internal view returns (uint256 balance) {\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n balance = balance.add(\\n _checkBalance(allAssets[i]).scaleBy(int8(18 - assetDecimals))\\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 * @notice Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned.\\n * @return 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 = getAssetCount();\\n uint256[] memory assetPrices = _getAssetPrices(true);\\n uint256[] memory assetBalances = new uint256[](assetCount);\\n uint256[] memory assetDecimals = new uint256[](assetCount);\\n uint256 totalBalance = 0;\\n uint256 totalOutputRatio = 0;\\n outputs = new uint256[](assetCount);\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mul(redeemFeeBps).div(10000);\\n _amount = _amount.sub(redeemFee);\\n }\\n\\n // Calculate assets balances and decimals once,\\n // for a large gas savings.\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 balance = _checkBalance(allAssets[i]);\\n uint256 decimals = Helpers.getDecimals(allAssets[i]);\\n assetBalances[i] = balance;\\n assetDecimals[i] = decimals;\\n totalBalance = totalBalance.add(\\n balance.scaleBy(int8(18 - decimals))\\n );\\n }\\n // Calculate totalOutputRatio\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 price = assetPrices[i];\\n // Never give out more than one\\n // stablecoin per dollar of OUSD\\n if (price < 1e18) {\\n price = 1e18;\\n }\\n uint256 ratio = assetBalances[i]\\n .scaleBy(int8(18 - assetDecimals[i]))\\n .mul(price)\\n .div(totalBalance);\\n totalOutputRatio = totalOutputRatio.add(ratio);\\n }\\n // Calculate final outputs\\n uint256 factor = _amount.divPrecisely(totalOutputRatio);\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n outputs[i] = assetBalances[i].mul(factor).div(totalBalance);\\n }\\n }\\n\\n /**\\n * @notice Get an array of the supported asset prices in USD.\\n * @return uint256[] Array of asset prices in USD (1e18)\\n */\\n function _getAssetPrices(bool useMax)\\n internal\\n view\\n returns (uint256[] memory assetPrices)\\n {\\n assetPrices = new uint256[](getAssetCount());\\n\\n IMinMaxOracle oracle = IMinMaxOracle(priceProvider);\\n // Price from Oracle is returned with 8 decimals\\n // _amount is in assetDecimals\\n\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n string memory symbol = Helpers.getSymbol(allAssets[i]);\\n // Get all the USD prices of the asset in 1e18\\n if (useMax) {\\n assetPrices[i] = oracle.priceMax(symbol).scaleBy(int8(18 - 8));\\n } else {\\n assetPrices[i] = oracle.priceMin(symbol).scaleBy(int8(18 - 8));\\n }\\n }\\n }\\n\\n /***************************************\\n Utils\\n ****************************************/\\n\\n /**\\n * @dev Return the number of assets suppported by the Vault.\\n */\\n function getAssetCount() public view returns (uint256) {\\n return allAssets.length;\\n }\\n\\n /**\\n * @dev Return all asset addresses in order\\n */\\n function getAllAssets() external view returns (address[] memory) {\\n return allAssets;\\n }\\n\\n /**\\n * @dev Return the number of strategies active on the Vault.\\n */\\n function getStrategyCount() external view returns (uint256) {\\n return allStrategies.length;\\n }\\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 function() external payable {\\n bytes32 slot = adminImplPosition;\\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(gas, sload(slot), 0, calldatasize, 0, 0)\\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\",\"keccak256\":\"0xb16df039956cf5aa13886f52ff6db1264a77726d81268e9165eb8a31f7f65d7b\"},\"contracts/vault/VaultStorage.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD 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/SafeERC20.sol\\\";\\nimport { SafeMath } from \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.sol\\\";\\n\\nimport { IStrategy } from \\\"../interfaces/IStrategy.sol\\\";\\nimport { Governable } from \\\"../governance/Governable.sol\\\";\\nimport { OUSD } from \\\"../token/OUSD.sol\\\";\\nimport \\\"../utils/Helpers.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\n\\ncontract VaultStorage is Initializable, Governable {\\n using SafeMath for uint256;\\n using StableMath for uint256;\\n using SafeMath for int256;\\n using SafeERC20 for IERC20;\\n\\n event AssetSupported(address _asset);\\n event AssetDefaultStrategyUpdated(address _asset, address _strategy);\\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 RedeemFeeUpdated(uint256 _redeemFeeBps);\\n event PriceProviderUpdated(address _priceProvider);\\n event AllocateThresholdUpdated(uint256 _threshold);\\n event RebaseThresholdUpdated(uint256 _threshold);\\n event UniswapUpdated(address _address);\\n event StrategistUpdated(address _address);\\n event MaxSupplyDiffChanged(uint256 maxSupplyDiff);\\n\\n // Assets supported by the Vault, i.e. Stablecoins\\n struct Asset {\\n bool isSupported;\\n }\\n mapping(address => Asset) assets;\\n address[] allAssets;\\n\\n // Strategies approved for use by the Vault\\n struct Strategy {\\n bool isSupported;\\n uint256 _deprecated; // Deprecated storage slot\\n }\\n mapping(address => Strategy) strategies;\\n address[] allStrategies;\\n\\n // Address of the Oracle price provider contract\\n address public priceProvider;\\n // Pausing bools\\n bool public rebasePaused = false;\\n bool public capitalPaused = true;\\n // Redemption fee in basis points\\n uint256 public redeemFeeBps;\\n // Buffer of assets to keep in Vault to handle (most) withdrawals\\n uint256 public vaultBuffer;\\n // Mints over this amount automatically allocate funds. 18 decimals.\\n uint256 public autoAllocateThreshold;\\n // Mints over this amount automatically rebase. 18 decimals.\\n uint256 public rebaseThreshold;\\n\\n OUSD oUSD;\\n\\n //keccak256(\\\"OUSD.vault.governor.admin.impl\\\");\\n bytes32 constant adminImplPosition = 0xa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9;\\n\\n // Address of the contract responsible for post rebase syncs with AMMs\\n address private _deprecated_rebaseHooksAddr = address(0);\\n\\n // Address of Uniswap\\n address public uniswapAddr = address(0);\\n\\n // Address of the Strategist\\n address public strategistAddr = address(0);\\n\\n // Mapping of asset address to the Strategy that they should automatically\\n // be allocated to\\n mapping(address => address) public assetDefaultStrategies;\\n\\n uint256 public maxSupplyDiff;\\n\\n /**\\n * @dev set the implementation for the admin, this needs to be in a base class else we cannot set it\\n * @param newImpl address pf the implementation\\n */\\n function setAdminImpl(address newImpl) external onlyGovernor {\\n bytes32 position = adminImplPosition;\\n assembly {\\n sstore(position, newImpl)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2e47ddd6070edf156bfe8be58f3f8fc677935f81ee5076c1b95444eed05eac33\"}},\"version\":1}", - "bytecode": "0x60806040526037805461ffff60a01b19167501000000000000000000000000000000000000000000179055603d80546001600160a01b0319908116909155603e805482169055603f8054909116905562000062336001600160e01b03620000bb16565b620000756001600160e01b03620000ce16565b6001600160a01b031660006001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3620000e2565b600080516020620037da83398151915255565b600080516020620037da8339815191525490565b6136e880620000f26000396000f3fe6080604052600436106101c25760003560e01c80637cbc2373116100f7578063af14052c11610095578063d4c3eea011610064578063d4c3eea014610590578063e6cc5432146105a5578063f0efb4c7146105ba578063fc0cfeee14610689576101c2565b8063af14052c1461051e578063b888879e14610533578063c7af335214610548578063d38bfff41461055d576101c2565b80639fa1826e116100d15780639fa1826e146104ac578063a0aead4d146104c1578063a403e4d5146104d6578063abaa991614610509576101c2565b80637cbc2373146104345780638e510b52146104645780639be918e614610479576101c2565b806352d38e5d116101645780635d36b1901161013e5780635d36b190146103985780635f515226146103ad57806367bd7ba3146103e05780637136a7a61461040a576101c2565b806352d38e5d1461034557806353ca9f241461035a578063570d8e1d14610383576101c2565b8063156e29f6116101a0578063156e29f6146102755780631edfe3da146102b65780632acada4d146102cb57806331e19cfa14610330576101c2565b806309f6442c146102085780630c340a241461022f578063128a8b0514610260575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610203573d6000f35b3d6000fd5b34801561021457600080fd5b5061021d6106bc565b60408051918252519081900360200190f35b34801561023b57600080fd5b506102446106c2565b604080516001600160a01b039092168252519081900360200190f35b34801561026c57600080fd5b506102446106d2565b34801561028157600080fd5b506102b46004803603606081101561029857600080fd5b506001600160a01b0381351690602081013590604001356106e1565b005b3480156102c257600080fd5b5061021d610af6565b3480156102d757600080fd5b506102e0610afc565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561031c578181015183820152602001610304565b505050509050019250505060405180910390f35b34801561033c57600080fd5b5061021d610b5e565b34801561035157600080fd5b5061021d610b64565b34801561036657600080fd5b5061036f610b6a565b604080519115158252519081900360200190f35b34801561038f57600080fd5b50610244610b7a565b3480156103a457600080fd5b506102b4610b89565b3480156103b957600080fd5b5061021d600480360360208110156103d057600080fd5b50356001600160a01b0316610beb565b3480156103ec57600080fd5b506102e06004803603602081101561040357600080fd5b5035610bfc565b34801561041657600080fd5b506102b46004803603602081101561042d57600080fd5b5035610c07565b34801561044057600080fd5b506102b46004803603604081101561045757600080fd5b5080359060200135610dd9565b34801561047057600080fd5b5061021d610ec2565b34801561048557600080fd5b5061036f6004803603602081101561049c57600080fd5b50356001600160a01b0316610ec8565b3480156104b857600080fd5b5061021d610ee6565b3480156104cd57600080fd5b5061021d610eec565b3480156104e257600080fd5b50610244600480360360208110156104f957600080fd5b50356001600160a01b0316610ef2565b34801561051557600080fd5b506102b4610f0d565b34801561052a57600080fd5b5061021d610fc8565b34801561053f57600080fd5b5061024461108a565b34801561055457600080fd5b5061036f611099565b34801561056957600080fd5b506102b46004803603602081101561058057600080fd5b50356001600160a01b03166110bc565b34801561059c57600080fd5b5061021d611168565b3480156105b157600080fd5b5061036f611172565b3480156105c657600080fd5b506102b4600480360360608110156105dd57600080fd5b8101906020810181356401000000008111156105f857600080fd5b82018360208201111561060a57600080fd5b8035906020019184602083028401116401000000008311171561062c57600080fd5b91939092909160208101903564010000000081111561064a57600080fd5b82018360208201111561065c57600080fd5b8035906020019184602083028401116401000000008311171561067e57600080fd5b919350915035611182565b34801561069557600080fd5b506102b4600480360360208110156106ac57600080fd5b50356001600160a01b031661167f565b60385481565b60006106cc6116fc565b90505b90565b603e546001600160a01b031681565b603754600160a81b900460ff1615610731576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610789576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff166107f3576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610848576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf061086588611721565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108b1578181015183820152602001610899565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156108fb57600080fd5b505afa15801561090f573d6000803e3d6000fd5b505050506040513d602081101561092557600080fd5b505190506305f5e10081111561093c57506305f5e1005b600061094787611852565b9050600061095f87601284900363ffffffff61190c16565b9050600061098961097785600a63ffffffff61190c16565b8990600a86900a63ffffffff61196616565b905086156109e657868110156109e6576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a3d5750603754600160a01b900460ff16155b15610a4c57610a4a611994565b505b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610a9f57600080fd5b505af1158015610ab3573d6000803e3d6000fd5b508b9250610ad59150506001600160a01b03821633308c63ffffffff611b5d16565b603a548310610ae657610ae6611bbd565b5050505050600182555050505050565b60395481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b5457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b36575b5050505050905090565b60365490565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610b916120ec565b6001600160a01b0316336001600160a01b031614610be05760405162461bcd60e51b81526004018080602001828103825260308152602001806136846030913960400191505060405180910390fd5b610be933612111565b565b6000610bf6826121bf565b92915050565b6060610bf682612380565b603754600160a81b900460ff1615610c57576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610caf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d0157600080fd5b505afa158015610d15573d6000803e3d6000fd5b505050506040513d6020811015610d2b57600080fd5b5051118015610d445750603754600160a01b900460ff16155b15610d5357610d51611994565b505b603c54604080516370a0823160e01b81523360048201529051610dd1926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610d9f57600080fd5b505afa158015610db3573d6000803e3d6000fd5b505050506040513d6020811015610dc957600080fd5b505184612641565b506001905550565b603754600160a81b900460ff1615610e29576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610e81576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ea05750603754600160a01b900460ff16155b15610eaf57610ead611994565b505b610eb98484612641565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610f5d576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610fb5576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255610fc1611bbd565b5060019055565b603754600090600160a01b900460ff161561101c576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415611074576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255611080611994565b9250506001905590565b6037546001600160a01b031681565b60006110a36116fc565b6001600160a01b0316336001600160a01b031614905090565b6110c4611099565b611115576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61111e81612bf3565b806001600160a01b03166111306116fc565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006106cc612c17565b603754600160a81b900460ff1681565b603754600160a81b900460ff16156111d2576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f08339815191528054600281141561122a576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255858414611282576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b600080606061129082612c38565b905060005b898110156114c957603360008c8c848181106112ad57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661131d576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061132b57fe5b9050602002013511611384576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b6034548110156114c0576034818154811061139e57fe5b6000918252602090912001546001600160a01b03168c8c848181106113bf57fe5b905060200201356001600160a01b03166001600160a01b031614156114b857600061140a603483815481106113f057fe5b6000918252602090912001546001600160a01b0316611852565b9050600084838151811061141a57fe5b60200260200101519050670de0b6b3a764000081111561143f5750670de0b6b3a76400005b61147761146a836012038e8e8881811061145557fe5b9050602002013561190c90919063ffffffff16565b889063ffffffff612e3e16565b96506114b36114a68284600a0a8f8f8981811061149057fe5b905060200201356119669092919063ffffffff16565b879063ffffffff612e3e16565b955050505b600101611387565b50600101611295565b5085156115255785821015611525576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b54831015801561157c5750603754600160a01b900460ff16155b1561158b57611589611994565b505b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b1580156115de57600080fd5b505af11580156115f2573d6000803e3d6000fd5b506000925050505b8981101561165d5760008b8b8381811061161057fe5b905060200201356001600160a01b0316905061165433308c8c8681811061163357fe5b90506020020135846001600160a01b0316611b5d909392919063ffffffff16565b506001016115fa565b50603a54831061166f5761166f611bbd565b5050506001825550505050505050565b611687611099565b6116d8576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561179a57600080fd5b81019080805160405193929190846401000000008211156117ba57600080fd5b9083019060208201858111156117cf57600080fd5b82516401000000008111828201881017156117e957600080fd5b82525081516020918201929091019080838360005b838110156118165781810151838201526020016117fe565b50505050905090810190601f1680156118435780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561188e57600080fd5b505afa1580156118a2573d6000803e3d6000fd5b505050506040513d60208110156118b857600080fd5b505160ff169050600481108015906118d1575060128111155b610bf65760405162461bcd60e51b81526004018080602001828103825260298152602001806136106029913960400191505060405180910390fd5b6000808260000b13156119375761193083600084900b600a0a63ffffffff612e9f16565b925061195f565b60008260000b121561195f5761195c836000848103900b600a0a63ffffffff612ef816565b92505b5090919050565b600080611979858563ffffffff612e9f16565b905061198b818463ffffffff612ef816565b95945050505050565b603754600090600160a01b900460ff16156119e8576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3657600080fd5b505afa158015611a4a573d6000803e3d6000fd5b505050506040513d6020811015611a6057600080fd5b5051611a6e575060006106cf565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611ab357600080fd5b505afa158015611ac7573d6000803e3d6000fd5b505050506040513d6020811015611add57600080fd5b50519050611ae9612c17565b915080821115611b5957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611b4057600080fd5b505af1158015611b54573d6000803e3d6000fd5b505050505b5090565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bb7908590612f3a565b50505050565b6000611bc76130f2565b905080611bd45750610be9565b6000611bde6131de565b90506000611bf2838363ffffffff612e3e16565b9050600082611c1e57603954611c1790670de0b6b3a76400009063ffffffff61323016565b9050611c76565b611c4384611c3784603954612e9f90919063ffffffff16565b9063ffffffff612ef816565b905080670de0b6b3a76400001115611c6d57611c17670de0b6b3a76400008263ffffffff61323016565b50505050610be9565b80611c845750505050610be9565b60005b603454811015611e1357600060348281548110611ca057fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611cf357600080fd5b505afa158015611d07573d6000803e3d6000fd5b505050506040513d6020811015611d1d57600080fd5b5051905080611d2d575050611e0b565b6000611d3f828663ffffffff61327216565b6001600160a01b03808516600090815260406020819052902054919250168015801590611d6c5750600082115b15611e065780611d8c6001600160a01b038616828563ffffffff61328716565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b50505050505b505050505b600101611c87565b5060005b6036548110156120e557600060368281548110611e3057fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b158015611e7d57600080fd5b505afa158015611e91573d6000803e3d6000fd5b505050506040513d6020811015611ea757600080fd5b505190506001600160a01b038116156120db576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d6020811015611f1f57600080fd5b5051905080611fae57306001600160a01b0316630e5c011e60368681548110611f4457fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b158015611f9157600080fd5b505af1158015611fa5573d6000803e3d6000fd5b505050506120d9565b60008290506000816001600160a01b03166370a0823160368881548110611fd157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561201f57600080fd5b505afa158015612033573d6000803e3d6000fd5b505050506040513d602081101561204957600080fd5b505190508281106120d657306001600160a01b0316630e5c011e6036888154811061207057fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b1580156120bd57600080fd5b505af11580156120d1573d6000803e3d6000fd5b505050505b50505b505b5050600101611e17565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b03811661216c576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661217e6116fc565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36121bc816132de565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561220a57600080fd5b505afa15801561221e573d6000803e3d6000fd5b505050506040513d602081101561223457600080fd5b5051915060005b6036548110156123795760006036828154811061225457fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b1580156122aa57600080fd5b505afa1580156122be573d6000803e3d6000fd5b505050506040513d60208110156122d457600080fd5b5051156123705761236d816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561233457600080fd5b505afa158015612348573d6000803e3d6000fd5b505050506040513d602081101561235e57600080fd5b5051859063ffffffff612e3e16565b93505b5060010161223b565b5050919050565b6060600061238c610eec565b9050606061239a6001612c38565b90506060826040519080825280602002602001820160405280156123c8578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156123f7578160200160208202803883390190505b506040805186815260208088028201019091529091506000908190868015612429578160200160208202803883390190505b5060385490975015612468576000612452612710611c376038548c612e9f90919063ffffffff16565b9050612464898263ffffffff61323016565b9850505b60005b6034548110156125185760006124a16034838154811061248757fe5b6000918252602090912001546001600160a01b03166121bf565b905060006124b5603484815481106113f057fe5b9050818784815181106124c457fe5b602002602001018181525050808684815181106124dd57fe5b602090810291909101015261250c6124ff83601284900363ffffffff61190c16565b869063ffffffff612e3e16565b9450505060010161246b565b5060005b6034548110156125c957600086828151811061253457fe5b60200260200101519050670de0b6b3a76400008110156125595750670de0b6b3a76400005b60006125ab85611c378461259f8a888151811061257257fe5b60200260200101516012038c898151811061258957fe5b602002602001015161190c90919063ffffffff16565b9063ffffffff612e9f16565b90506125bd848263ffffffff612e3e16565b9350505060010161251c565b5060006125dc898363ffffffff61330216565b905060005b6034548110156126345761261584611c37848985815181106125ff57fe5b6020026020010151612e9f90919063ffffffff16565b89828151811061262157fe5b60209081029190910101526001016125e1565b5050505050505050919050565b60008211612696576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156126db57600080fd5b505afa1580156126ef573d6000803e3d6000fd5b505050506040513d602081101561270557600080fd5b505190506000612713612c17565b604154909150156127ce576000612730838363ffffffff61330216565b9050604154670de0b6b3a764000082116127615761275c670de0b6b3a76400008363ffffffff61323016565b612779565b61277982670de0b6b3a764000063ffffffff61323016565b11156127cc576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a1606061281485612380565b905060005b603454811015612aaa5781818151811061282f57fe5b60200260200101516000141561284457612aa2565b60006034828154811061285357fe5b60009182526020909120015483516001600160a01b03909116915083908390811061287a57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128d857600080fd5b505afa1580156128ec573d6000803e3d6000fd5b505050506040513d602081101561290257600080fd5b50511061293f5761293a3384848151811061291957fe5b6020026020010151836001600160a01b03166132879092919063ffffffff16565b612aa0565b6000604060006034858154811061295257fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612a5f576000819050806001600160a01b031663d9caed1233603487815481106129a757fe5b9060005260206000200160009054906101000a90046001600160a01b03168888815181106129d157fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612a4157600080fd5b505af1158015612a55573d6000803e3d6000fd5b5050505050612a9e565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b600101612819565b508315612b58576000805b8251811015612b00576000612ad0603483815481106113f057fe5b9050612af5612ae88260120386858151811061258957fe5b849063ffffffff612e3e16565b925050600101612ab5565b5084811015612b56576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612bab57600080fd5b505af1158015612bbf573d6000803e3d6000fd5b50505050603b5485118015612bde5750603754600160a01b900460ff16155b156120e557612beb611994565b505050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b60006106cc612c246131de565b612c2c6130f2565b9063ffffffff612e3e16565b6060612c42610eec565b604051908082528060200260200182016040528015612c6b578160200160208202803883390190505b506037549091506001600160a01b031660005b603454811015612379576060612cb460348381548110612c9a57fe5b6000918252602090912001546001600160a01b0316611721565b90508415612dbc57612d9f600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d1d578181015183820152602001612d05565b50505050905090810190601f168015612d4a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612d6757600080fd5b505afa158015612d7b573d6000803e3d6000fd5b505050506040513d6020811015612d9157600080fd5b50519063ffffffff61190c16565b848381518110612dab57fe5b602002602001018181525050612e35565b60405163019af6bf60e41b8152602060048201818152835160248401528351612e1c93600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612d1d578181015183820152602001612d05565b848381518110612e2857fe5b6020026020010181815250505b50600101612c7e565b600082820183811015612e98576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082612eae57506000610bf6565b82820282848281612ebb57fe5b0414612e985760405162461bcd60e51b81526004018080602001828103825260218152602001806136396021913960400191505060405180910390fd5b6000612e9883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613337565b612f4c826001600160a01b03166133d9565b612f9d576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612fdb5780518252601f199092019160209182019101612fbc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461303d576040519150601f19603f3d011682016040523d82523d6000602084013e613042565b606091505b509150915081613099576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611bb7578080602001905160208110156130b557600080fd5b5051611bb75760405162461bcd60e51b815260040180806020018281038252602a81526020018061365a602a913960400191505060405180910390fd5b6000805b603454811015611b595760006034828154811061310f57fe5b6000918252602082200154603480546001600160a01b03909216935061313991859081106113f057fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d60208110156131af57600080fd5b5051905080156131d3576131d06124ff82601285900363ffffffff61190c16565b94505b5050506001016130f6565b6000805b603654811015611b5957613226613219603683815481106131ff57fe5b6000918252602090912001546001600160a01b0316613412565b839063ffffffff612e3e16565b91506001016131e2565b6000612e9883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613595565b6000612e988383670de0b6b3a7640000611966565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526132d9908490612f3a565b505050565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061331d84670de0b6b3a764000063ffffffff612e9f16565b905061332f818463ffffffff612ef816565b949350505050565b600081836133c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613388578181015183820152602001613370565b50505050905090810190601f1680156133b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816133cf57fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061332f575050151592915050565b600081815b603454811015612379576000613433603483815481106113f057fe5b9050826001600160a01b031663aa388af66034848154811061345157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561349f57600080fd5b505afa1580156134b3573d6000803e3d6000fd5b505050506040513d60208110156134c957600080fd5b50511561358c576000836001600160a01b0316635f515226603485815481106134ee57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561353c57600080fd5b505afa158015613550573d6000803e3d6000fd5b505050506040513d602081101561356657600080fd5b50519050801561358a576135876124ff82601285900363ffffffff61190c16565b94505b505b50600101613417565b600081848411156135e75760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613388578181015183820152602001613370565b50505090039056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a72315820ab97d4c53e4ef80d280841f43291bad1192e147995980878462b60004ce5f35164736f6c634300050b00327bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a", - "deployedBytecode": "0x6080604052600436106101c25760003560e01c80637cbc2373116100f7578063af14052c11610095578063d4c3eea011610064578063d4c3eea014610590578063e6cc5432146105a5578063f0efb4c7146105ba578063fc0cfeee14610689576101c2565b8063af14052c1461051e578063b888879e14610533578063c7af335214610548578063d38bfff41461055d576101c2565b80639fa1826e116100d15780639fa1826e146104ac578063a0aead4d146104c1578063a403e4d5146104d6578063abaa991614610509576101c2565b80637cbc2373146104345780638e510b52146104645780639be918e614610479576101c2565b806352d38e5d116101645780635d36b1901161013e5780635d36b190146103985780635f515226146103ad57806367bd7ba3146103e05780637136a7a61461040a576101c2565b806352d38e5d1461034557806353ca9f241461035a578063570d8e1d14610383576101c2565b8063156e29f6116101a0578063156e29f6146102755780631edfe3da146102b65780632acada4d146102cb57806331e19cfa14610330576101c2565b806309f6442c146102085780630c340a241461022f578063128a8b0514610260575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610203573d6000f35b3d6000fd5b34801561021457600080fd5b5061021d6106bc565b60408051918252519081900360200190f35b34801561023b57600080fd5b506102446106c2565b604080516001600160a01b039092168252519081900360200190f35b34801561026c57600080fd5b506102446106d2565b34801561028157600080fd5b506102b46004803603606081101561029857600080fd5b506001600160a01b0381351690602081013590604001356106e1565b005b3480156102c257600080fd5b5061021d610af6565b3480156102d757600080fd5b506102e0610afc565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561031c578181015183820152602001610304565b505050509050019250505060405180910390f35b34801561033c57600080fd5b5061021d610b5e565b34801561035157600080fd5b5061021d610b64565b34801561036657600080fd5b5061036f610b6a565b604080519115158252519081900360200190f35b34801561038f57600080fd5b50610244610b7a565b3480156103a457600080fd5b506102b4610b89565b3480156103b957600080fd5b5061021d600480360360208110156103d057600080fd5b50356001600160a01b0316610beb565b3480156103ec57600080fd5b506102e06004803603602081101561040357600080fd5b5035610bfc565b34801561041657600080fd5b506102b46004803603602081101561042d57600080fd5b5035610c07565b34801561044057600080fd5b506102b46004803603604081101561045757600080fd5b5080359060200135610dd9565b34801561047057600080fd5b5061021d610ec2565b34801561048557600080fd5b5061036f6004803603602081101561049c57600080fd5b50356001600160a01b0316610ec8565b3480156104b857600080fd5b5061021d610ee6565b3480156104cd57600080fd5b5061021d610eec565b3480156104e257600080fd5b50610244600480360360208110156104f957600080fd5b50356001600160a01b0316610ef2565b34801561051557600080fd5b506102b4610f0d565b34801561052a57600080fd5b5061021d610fc8565b34801561053f57600080fd5b5061024461108a565b34801561055457600080fd5b5061036f611099565b34801561056957600080fd5b506102b46004803603602081101561058057600080fd5b50356001600160a01b03166110bc565b34801561059c57600080fd5b5061021d611168565b3480156105b157600080fd5b5061036f611172565b3480156105c657600080fd5b506102b4600480360360608110156105dd57600080fd5b8101906020810181356401000000008111156105f857600080fd5b82018360208201111561060a57600080fd5b8035906020019184602083028401116401000000008311171561062c57600080fd5b91939092909160208101903564010000000081111561064a57600080fd5b82018360208201111561065c57600080fd5b8035906020019184602083028401116401000000008311171561067e57600080fd5b919350915035611182565b34801561069557600080fd5b506102b4600480360360208110156106ac57600080fd5b50356001600160a01b031661167f565b60385481565b60006106cc6116fc565b90505b90565b603e546001600160a01b031681565b603754600160a81b900460ff1615610731576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610789576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff166107f3576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610848576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf061086588611721565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108b1578181015183820152602001610899565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156108fb57600080fd5b505afa15801561090f573d6000803e3d6000fd5b505050506040513d602081101561092557600080fd5b505190506305f5e10081111561093c57506305f5e1005b600061094787611852565b9050600061095f87601284900363ffffffff61190c16565b9050600061098961097785600a63ffffffff61190c16565b8990600a86900a63ffffffff61196616565b905086156109e657868110156109e6576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a3d5750603754600160a01b900460ff16155b15610a4c57610a4a611994565b505b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610a9f57600080fd5b505af1158015610ab3573d6000803e3d6000fd5b508b9250610ad59150506001600160a01b03821633308c63ffffffff611b5d16565b603a548310610ae657610ae6611bbd565b5050505050600182555050505050565b60395481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b5457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b36575b5050505050905090565b60365490565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610b916120ec565b6001600160a01b0316336001600160a01b031614610be05760405162461bcd60e51b81526004018080602001828103825260308152602001806136846030913960400191505060405180910390fd5b610be933612111565b565b6000610bf6826121bf565b92915050565b6060610bf682612380565b603754600160a81b900460ff1615610c57576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610caf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d0157600080fd5b505afa158015610d15573d6000803e3d6000fd5b505050506040513d6020811015610d2b57600080fd5b5051118015610d445750603754600160a01b900460ff16155b15610d5357610d51611994565b505b603c54604080516370a0823160e01b81523360048201529051610dd1926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610d9f57600080fd5b505afa158015610db3573d6000803e3d6000fd5b505050506040513d6020811015610dc957600080fd5b505184612641565b506001905550565b603754600160a81b900460ff1615610e29576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610e81576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ea05750603754600160a01b900460ff16155b15610eaf57610ead611994565b505b610eb98484612641565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610f5d576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415610fb5576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255610fc1611bbd565b5060019055565b603754600090600160a01b900460ff161561101c576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206135f083398151915280546002811415611074576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255611080611994565b9250506001905590565b6037546001600160a01b031681565b60006110a36116fc565b6001600160a01b0316336001600160a01b031614905090565b6110c4611099565b611115576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61111e81612bf3565b806001600160a01b03166111306116fc565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b60006106cc612c17565b603754600160a81b900460ff1681565b603754600160a81b900460ff16156111d2576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206135f08339815191528054600281141561122a576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255858414611282576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b600080606061129082612c38565b905060005b898110156114c957603360008c8c848181106112ad57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661131d576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061132b57fe5b9050602002013511611384576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b6034548110156114c0576034818154811061139e57fe5b6000918252602090912001546001600160a01b03168c8c848181106113bf57fe5b905060200201356001600160a01b03166001600160a01b031614156114b857600061140a603483815481106113f057fe5b6000918252602090912001546001600160a01b0316611852565b9050600084838151811061141a57fe5b60200260200101519050670de0b6b3a764000081111561143f5750670de0b6b3a76400005b61147761146a836012038e8e8881811061145557fe5b9050602002013561190c90919063ffffffff16565b889063ffffffff612e3e16565b96506114b36114a68284600a0a8f8f8981811061149057fe5b905060200201356119669092919063ffffffff16565b879063ffffffff612e3e16565b955050505b600101611387565b50600101611295565b5085156115255785821015611525576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b54831015801561157c5750603754600160a01b900460ff16155b1561158b57611589611994565b505b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b1580156115de57600080fd5b505af11580156115f2573d6000803e3d6000fd5b506000925050505b8981101561165d5760008b8b8381811061161057fe5b905060200201356001600160a01b0316905061165433308c8c8681811061163357fe5b90506020020135846001600160a01b0316611b5d909392919063ffffffff16565b506001016115fa565b50603a54831061166f5761166f611bbd565b5050506001825550505050505050565b611687611099565b6116d8576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561175d57600080fd5b505afa158015611771573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561179a57600080fd5b81019080805160405193929190846401000000008211156117ba57600080fd5b9083019060208201858111156117cf57600080fd5b82516401000000008111828201881017156117e957600080fd5b82525081516020918201929091019080838360005b838110156118165781810151838201526020016117fe565b50505050905090810190601f1680156118435780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561188e57600080fd5b505afa1580156118a2573d6000803e3d6000fd5b505050506040513d60208110156118b857600080fd5b505160ff169050600481108015906118d1575060128111155b610bf65760405162461bcd60e51b81526004018080602001828103825260298152602001806136106029913960400191505060405180910390fd5b6000808260000b13156119375761193083600084900b600a0a63ffffffff612e9f16565b925061195f565b60008260000b121561195f5761195c836000848103900b600a0a63ffffffff612ef816565b92505b5090919050565b600080611979858563ffffffff612e9f16565b905061198b818463ffffffff612ef816565b95945050505050565b603754600090600160a01b900460ff16156119e8576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3657600080fd5b505afa158015611a4a573d6000803e3d6000fd5b505050506040513d6020811015611a6057600080fd5b5051611a6e575060006106cf565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611ab357600080fd5b505afa158015611ac7573d6000803e3d6000fd5b505050506040513d6020811015611add57600080fd5b50519050611ae9612c17565b915080821115611b5957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611b4057600080fd5b505af1158015611b54573d6000803e3d6000fd5b505050505b5090565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bb7908590612f3a565b50505050565b6000611bc76130f2565b905080611bd45750610be9565b6000611bde6131de565b90506000611bf2838363ffffffff612e3e16565b9050600082611c1e57603954611c1790670de0b6b3a76400009063ffffffff61323016565b9050611c76565b611c4384611c3784603954612e9f90919063ffffffff16565b9063ffffffff612ef816565b905080670de0b6b3a76400001115611c6d57611c17670de0b6b3a76400008263ffffffff61323016565b50505050610be9565b80611c845750505050610be9565b60005b603454811015611e1357600060348281548110611ca057fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611cf357600080fd5b505afa158015611d07573d6000803e3d6000fd5b505050506040513d6020811015611d1d57600080fd5b5051905080611d2d575050611e0b565b6000611d3f828663ffffffff61327216565b6001600160a01b03808516600090815260406020819052902054919250168015801590611d6c5750600082115b15611e065780611d8c6001600160a01b038616828563ffffffff61328716565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b50505050505b505050505b600101611c87565b5060005b6036548110156120e557600060368281548110611e3057fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b158015611e7d57600080fd5b505afa158015611e91573d6000803e3d6000fd5b505050506040513d6020811015611ea757600080fd5b505190506001600160a01b038116156120db576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d6020811015611f1f57600080fd5b5051905080611fae57306001600160a01b0316630e5c011e60368681548110611f4457fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b158015611f9157600080fd5b505af1158015611fa5573d6000803e3d6000fd5b505050506120d9565b60008290506000816001600160a01b03166370a0823160368881548110611fd157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561201f57600080fd5b505afa158015612033573d6000803e3d6000fd5b505050506040513d602081101561204957600080fd5b505190508281106120d657306001600160a01b0316630e5c011e6036888154811061207057fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b1580156120bd57600080fd5b505af11580156120d1573d6000803e3d6000fd5b505050505b50505b505b5050600101611e17565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b03811661216c576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661217e6116fc565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a36121bc816132de565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b15801561220a57600080fd5b505afa15801561221e573d6000803e3d6000fd5b505050506040513d602081101561223457600080fd5b5051915060005b6036548110156123795760006036828154811061225457fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b1580156122aa57600080fd5b505afa1580156122be573d6000803e3d6000fd5b505050506040513d60208110156122d457600080fd5b5051156123705761236d816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561233457600080fd5b505afa158015612348573d6000803e3d6000fd5b505050506040513d602081101561235e57600080fd5b5051859063ffffffff612e3e16565b93505b5060010161223b565b5050919050565b6060600061238c610eec565b9050606061239a6001612c38565b90506060826040519080825280602002602001820160405280156123c8578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156123f7578160200160208202803883390190505b506040805186815260208088028201019091529091506000908190868015612429578160200160208202803883390190505b5060385490975015612468576000612452612710611c376038548c612e9f90919063ffffffff16565b9050612464898263ffffffff61323016565b9850505b60005b6034548110156125185760006124a16034838154811061248757fe5b6000918252602090912001546001600160a01b03166121bf565b905060006124b5603484815481106113f057fe5b9050818784815181106124c457fe5b602002602001018181525050808684815181106124dd57fe5b602090810291909101015261250c6124ff83601284900363ffffffff61190c16565b869063ffffffff612e3e16565b9450505060010161246b565b5060005b6034548110156125c957600086828151811061253457fe5b60200260200101519050670de0b6b3a76400008110156125595750670de0b6b3a76400005b60006125ab85611c378461259f8a888151811061257257fe5b60200260200101516012038c898151811061258957fe5b602002602001015161190c90919063ffffffff16565b9063ffffffff612e9f16565b90506125bd848263ffffffff612e3e16565b9350505060010161251c565b5060006125dc898363ffffffff61330216565b905060005b6034548110156126345761261584611c37848985815181106125ff57fe5b6020026020010151612e9f90919063ffffffff16565b89828151811061262157fe5b60209081029190910101526001016125e1565b5050505050505050919050565b60008211612696576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156126db57600080fd5b505afa1580156126ef573d6000803e3d6000fd5b505050506040513d602081101561270557600080fd5b505190506000612713612c17565b604154909150156127ce576000612730838363ffffffff61330216565b9050604154670de0b6b3a764000082116127615761275c670de0b6b3a76400008363ffffffff61323016565b612779565b61277982670de0b6b3a764000063ffffffff61323016565b11156127cc576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a1606061281485612380565b905060005b603454811015612aaa5781818151811061282f57fe5b60200260200101516000141561284457612aa2565b60006034828154811061285357fe5b60009182526020909120015483516001600160a01b03909116915083908390811061287a57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156128d857600080fd5b505afa1580156128ec573d6000803e3d6000fd5b505050506040513d602081101561290257600080fd5b50511061293f5761293a3384848151811061291957fe5b6020026020010151836001600160a01b03166132879092919063ffffffff16565b612aa0565b6000604060006034858154811061295257fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612a5f576000819050806001600160a01b031663d9caed1233603487815481106129a757fe5b9060005260206000200160009054906101000a90046001600160a01b03168888815181106129d157fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612a4157600080fd5b505af1158015612a55573d6000803e3d6000fd5b5050505050612a9e565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b600101612819565b508315612b58576000805b8251811015612b00576000612ad0603483815481106113f057fe5b9050612af5612ae88260120386858151811061258957fe5b849063ffffffff612e3e16565b925050600101612ab5565b5084811015612b56576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612bab57600080fd5b505af1158015612bbf573d6000803e3d6000fd5b50505050603b5485118015612bde5750603754600160a01b900460ff16155b156120e557612beb611994565b505050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b60006106cc612c246131de565b612c2c6130f2565b9063ffffffff612e3e16565b6060612c42610eec565b604051908082528060200260200182016040528015612c6b578160200160208202803883390190505b506037549091506001600160a01b031660005b603454811015612379576060612cb460348381548110612c9a57fe5b6000918252602090912001546001600160a01b0316611721565b90508415612dbc57612d9f600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612d1d578181015183820152602001612d05565b50505050905090810190601f168015612d4a5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612d6757600080fd5b505afa158015612d7b573d6000803e3d6000fd5b505050506040513d6020811015612d9157600080fd5b50519063ffffffff61190c16565b848381518110612dab57fe5b602002602001018181525050612e35565b60405163019af6bf60e41b8152602060048201818152835160248401528351612e1c93600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612d1d578181015183820152602001612d05565b848381518110612e2857fe5b6020026020010181815250505b50600101612c7e565b600082820183811015612e98576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600082612eae57506000610bf6565b82820282848281612ebb57fe5b0414612e985760405162461bcd60e51b81526004018080602001828103825260218152602001806136396021913960400191505060405180910390fd5b6000612e9883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613337565b612f4c826001600160a01b03166133d9565b612f9d576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310612fdb5780518252601f199092019160209182019101612fbc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461303d576040519150601f19603f3d011682016040523d82523d6000602084013e613042565b606091505b509150915081613099576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611bb7578080602001905160208110156130b557600080fd5b5051611bb75760405162461bcd60e51b815260040180806020018281038252602a81526020018061365a602a913960400191505060405180910390fd5b6000805b603454811015611b595760006034828154811061310f57fe5b6000918252602082200154603480546001600160a01b03909216935061313991859081106113f057fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d60208110156131af57600080fd5b5051905080156131d3576131d06124ff82601285900363ffffffff61190c16565b94505b5050506001016130f6565b6000805b603654811015611b5957613226613219603683815481106131ff57fe5b6000918252602090912001546001600160a01b0316613412565b839063ffffffff612e3e16565b91506001016131e2565b6000612e9883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613595565b6000612e988383670de0b6b3a7640000611966565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526132d9908490612f3a565b505050565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061331d84670de0b6b3a764000063ffffffff612e9f16565b905061332f818463ffffffff612ef816565b949350505050565b600081836133c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613388578181015183820152602001613370565b50505050905090810190601f1680156133b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816133cf57fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061332f575050151592915050565b600081815b603454811015612379576000613433603483815481106113f057fe5b9050826001600160a01b031663aa388af66034848154811061345157fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561349f57600080fd5b505afa1580156134b3573d6000803e3d6000fd5b505050506040513d60208110156134c957600080fd5b50511561358c576000836001600160a01b0316635f515226603485815481106134ee57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561353c57600080fd5b505afa158015613550573d6000803e3d6000fd5b505050506040513d602081101561356657600080fd5b50519050801561358a576135876124ff82601285900363ffffffff61190c16565b94505b505b50600101613417565b600081848411156135e75760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613388578181015183820152602001613370565b50505090039056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a72315820ab97d4c53e4ef80d280841f43291bad1192e147995980878462b60004ce5f35164736f6c634300050b0032", + "solcInputHash": "c3af786fe12b6b771320281cb59e3482", + "metadata": "{\"compiler\":{\"version\":\"0.5.11+commit.22be8592.mod\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"redeemFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"uniswapAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vaultBuffer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"trusteeFeeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAllAssets\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getStrategyCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"trusteeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebaseThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"rebasePaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"strategistAddr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"claimGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"checkBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"calculateRedeemOutputs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeemAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minimumUnitAmount\",\"type\":\"uint256\"}],\"name\":\"redeem\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxSupplyDiff\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"isSupportedAsset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"autoAllocateThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getAssetCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"assetDefaultStrategies\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"allocate\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rebase\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"priceProvider\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isGovernor\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newGovernor\",\"type\":\"address\"}],\"name\":\"transferGovernance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"capitalPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_assets\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_minimumOusdAmount\",\"type\":\"uint256\"}],\"name\":\"mintMultiple\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImpl\",\"type\":\"address\"}],\"name\":\"setAdminImpl\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_asset\",\"type\":\"address\"}],\"name\":\"AssetSupported\",\"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\":\"_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\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"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\":[],\"name\":\"CapitalPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CapitalUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebasePaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"RebaseUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_vaultBuffer\",\"type\":\"uint256\"}],\"name\":\"VaultBufferUpdated\",\"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\":\"_priceProvider\",\"type\":\"address\"}],\"name\":\"PriceProviderUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"AllocateThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_threshold\",\"type\":\"uint256\"}],\"name\":\"RebaseThresholdUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"UniswapUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"StrategistUpdated\",\"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\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_yield\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"YieldDistribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_basis\",\"type\":\"uint256\"}],\"name\":\"TrusteeFeeBpsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"TrusteeAddressChanged\",\"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\":true,\"internalType\":\"address\",\"name\":\"previousGovernor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newGovernor\",\"type\":\"address\"}],\"name\":\"GovernorshipTransferred\",\"type\":\"event\"}],\"devdoc\":{\"methods\":{\"allocate()\":{\"details\":\"Allocate unallocated funds on Vault to strategies.*\"},\"checkBalance(address)\":{\"params\":{\"_asset\":\"Address of asset\"},\"return\":\"uint256 Balance of asset in decimals of asset\"},\"claimGovernance()\":{\"details\":\"Claim Governance of the contract to a new account (`newGovernor`). Can only be called by the new Governor.\"},\"getAllAssets()\":{\"details\":\"Return all asset addresses in order\"},\"getAssetCount()\":{\"details\":\"Return the number of assets suppported by the Vault.\"},\"getStrategyCount()\":{\"details\":\"Return the number of strategies active on the Vault.\"},\"governor()\":{\"details\":\"Returns the address of the current Governor.\"},\"isGovernor()\":{\"details\":\"Returns true if the caller is the current Governor.\"},\"mint(address,uint256,uint256)\":{\"details\":\"Deposit a supported asset and mint OUSD.\",\"params\":{\"_amount\":\"Amount of the asset being deposited\",\"_asset\":\"Address of the asset being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"mintMultiple(address[],uint256[],uint256)\":{\"details\":\"Mint for multiple assets in the same call.\",\"params\":{\"_amounts\":\"Amount of each asset at the same index in the _assets to deposit.\",\"_assets\":\"Addresses of assets being deposited\",\"_minimumOusdAmount\":\"Minimum OUSD to mint\"}},\"rebase()\":{\"details\":\"Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD.\"},\"redeem(uint256,uint256)\":{\"details\":\"Withdraw a supported asset and burn OUSD.\",\"params\":{\"_amount\":\"Amount of OUSD to burn\",\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"redeemAll(uint256)\":{\"params\":{\"_minimumUnitAmount\":\"Minimum stablecoin units to receive in return\"}},\"setAdminImpl(address)\":{\"details\":\"set the implementation for the admin, this needs to be in a base class else we cannot set it\",\"params\":{\"newImpl\":\"address of the implementation\"}},\"totalValue()\":{\"details\":\"Determine the total value of assets held by the vault and its strategies.\",\"return\":\"uint256 value Total value in USD (1e18)\"},\"transferGovernance(address)\":{\"details\":\"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\",\"params\":{\"_newGovernor\":\"Address of the new Governor\"}}}},\"userdoc\":{\"methods\":{\"allocate()\":{\"notice\":\"Allocate unallocated funds on Vault to strategies.\"},\"calculateRedeemOutputs(uint256)\":{\"notice\":\"Calculate the outputs for a redeem function, i.e. the mix of coins that will be returned\"},\"checkBalance(address)\":{\"notice\":\"Get the balance of an asset held in Vault and all strategies.\"},\"redeemAll(uint256)\":{\"notice\":\"Withdraw a supported asset and burn all OUSD.\"}}}},\"settings\":{\"compilationTarget\":{\"contracts/vault/VaultCore.sol\":\"VaultCore\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"metadata\":{\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n * - Subtraction cannot overflow.\\n *\\n * _Available since v2.4.0._\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n // Solidity only automatically asserts when dividing by 0\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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 * - The divisor cannot be zero.\\n *\\n * _Available since v2.4.0._\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x640b6dee7a4b830bdfd52b5031a07fc2b12209f5b2e29e5d364a7d37f69d8076\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\\n * the optional functions; to access them see {ERC20Detailed}.\\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(address sender, address recipient, uint256 amount) 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\":\"0xe5bb0f57cff3e299f360052ba50f1ea0fff046df2be070b6943e0e3c3fdad8a9\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"pragma solidity ^0.5.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 ERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n function safeApprove(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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.\\n\\n // A Solidity high level call has three parts:\\n // 1. The target address is checked to verify it contains contract code\\n // 2. The call itself is made, and success asserted\\n // 3. The return value is decoded, which in turn checks the size of the returned data.\\n // solhint-disable-next-line max-line-length\\n require(address(token).isContract(), \\\"SafeERC20: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = address(token).call(data);\\n require(success, \\\"SafeERC20: low-level call failed\\\");\\n\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6f2c9955d65c522b80f4b8792f076512d2df947d2112cbc4d98a4781ed42ede2\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"pragma solidity ^0.5.5;\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Converts an `address` into `address payable`. Note that this is\\n * simply a type cast: the actual underlying value is not changed.\\n *\\n * _Available since v2.4.0._\\n */\\n function toPayable(address account) internal pure returns (address payable) {\\n return address(uint160(account));\\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 * _Available since v2.4.0._\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-call-value\\n (bool success, ) = recipient.call.value(amount)(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0x1a8e5072509c5ea7365eb1d48030b9be865140c8fb779968da0a459a0e174a11\"},\"@openzeppelin/upgrades/contracts/Initializable.sol\":{\"content\":\"pragma solidity >=0.4.24 <0.7.0;\\n\\n\\n/**\\n * @title Initializable\\n *\\n * @dev Helper contract to support initializer functions. To use it, replace\\n * the constructor with a function that has the `initializer` modifier.\\n * WARNING: Unlike constructors, initializer functions must be manually\\n * invoked. This applies both to deploying an Initializable contract, as well\\n * as extending an Initializable contract via inheritance.\\n * WARNING: When used with inheritance, manual care must be taken to not invoke\\n * a parent initializer twice, or ensure that all initializers are idempotent,\\n * because this is not dealt with automatically as with constructors.\\n */\\ncontract Initializable {\\n\\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 use in the initializer function of a contract.\\n */\\n modifier initializer() {\\n require(initializing || isConstructor() || !initialized, \\\"Contract instance has already been initialized\\\");\\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 /// @dev Returns true if and only if the function is running in the constructor\\n function isConstructor() private view returns (bool) {\\n // extcodesize checks the size of the code stored in an address, and\\n // address returns the current address. Since the code is still not\\n // deployed when running a constructor, any checks on its code size will\\n // yield zero, making it an effective way to detect if a contract is\\n // under construction or not.\\n address self = address(this);\\n uint256 cs;\\n assembly { cs := extcodesize(self) }\\n return cs == 0;\\n }\\n\\n // Reserved storage space to allow for layout changes in the future.\\n uint256[50] private ______gap;\\n}\\n\",\"keccak256\":\"0x9bfec92e36234ecc99b5d37230acb6cd1f99560233753162204104a4897e8721\"},\"contracts/governance/Governable.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Governable Contract\\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\\n private constant governorPosition = 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\\n\\n // keccak256(\\\"OUSD.pending.governor\\\");\\n bytes32\\n private constant pendingGovernorPosition = 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\\n\\n // keccak256(\\\"OUSD.reentry.status\\\");\\n bytes32\\n private constant reentryStatusPosition = 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() internal {\\n _setGovernor(msg.sender);\\n emit GovernorshipTransferred(address(0), _governor());\\n }\\n\\n /**\\n * @dev 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 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 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 * @dev 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 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 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 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 assembly {\\n sstore(position, _NOT_ENTERED)\\n }\\n }\\n\\n function _setPendingGovernor(address newGovernor) internal {\\n bytes32 position = pendingGovernorPosition;\\n assembly {\\n sstore(position, newGovernor)\\n }\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0x3e51ea48102945bf4b305bf9722a07514a585a29555d92f8c84352d1a4cfcee1\"},\"contracts/interfaces/IBasicToken.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IBasicToken {\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x01eab42b6d54fa5389598e0663c24680ecc017e2da848e8ea1c40aeaa8225eef\"},\"contracts/interfaces/IMinMaxOracle.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IMinMaxOracle {\\n //Assuming 8 decimals\\n function priceMin(string calldata symbol) external view returns (uint256);\\n\\n function priceMax(string calldata symbol) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x164c8759ca5a8e39bbe1de6b2504098c543b2f15663c9d452e083418f8313f48\"},\"contracts/interfaces/IStrategy.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 Lending 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 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 collectRewardToken() external;\\n\\n /**\\n * @dev The address of the reward token for the Strategy.\\n */\\n function rewardTokenAddress() external pure returns (address);\\n\\n /**\\n * @dev The threshold (denominated in the reward token) over which the\\n * vault will auto harvest on allocate calls.\\n */\\n function rewardLiquidationThreshold() external pure returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9ef9546d60635c630e3446f270bc93f34593f5c77db8c671146f6c1eb0b2774\"},\"contracts/interfaces/IVault.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\ninterface IVault {\\n event AssetSupported(address _asset);\\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 DepositsPaused();\\n event DepositsUnpaused();\\n\\n // Governable.sol\\n function transferGovernance(address _newGovernor) external;\\n\\n function claimGovernance() external;\\n\\n function governor() external view returns (address);\\n\\n // VaultAdmin.sol\\n function setPriceProvider(address _priceProvider) external;\\n\\n function priceProvider() external view returns (address);\\n\\n function setRedeemFeeBps(uint256 _redeemFeeBps) external;\\n\\n function redeemFeeBps() external view returns (uint256);\\n\\n function setVaultBuffer(uint256 _vaultBuffer) external;\\n\\n function vaultBuffer() external view returns (uint256);\\n\\n function setAutoAllocateThreshold(uint256 _threshold) external;\\n\\n function autoAllocateThreshold() external view returns (uint256);\\n\\n function setRebaseThreshold(uint256 _threshold) external;\\n\\n function rebaseThreshold() external view returns (uint256);\\n\\n function setStrategistAddr(address _address) external;\\n\\n function strategistAddr() external view returns (address);\\n\\n function setUniswapAddr(address _address) external;\\n\\n function uniswapAddr() external view returns (address);\\n\\n function setMaxSupplyDiff(uint256 _maxSupplyDiff) external;\\n\\n function maxSupplyDiff() external view returns (uint256);\\n\\n function setTrusteeAddress(address _address) external;\\n\\n function trusteeAddress() external view returns (address);\\n\\n function setTrusteeFeeBps(uint256 _basis) external;\\n\\n function trusteeFeeBps() external view returns (uint256);\\n\\n function supportAsset(address _asset) external;\\n\\n function approveStrategy(address _addr) external;\\n\\n function removeStrategy(address _addr) external;\\n\\n function setAssetDefaultStrategy(address _asset, address _strategy)\\n external;\\n\\n function assetDefaultStrategies(address _asset)\\n external\\n view\\n returns (address);\\n\\n function pauseRebase() external;\\n\\n function unpauseRebase() external;\\n\\n function rebasePaused() external view returns (bool);\\n\\n function pauseCapital() external;\\n\\n function unpauseCapital() external;\\n\\n function capitalPaused() external view returns (bool);\\n\\n function transferToken(address _asset, uint256 _amount) external;\\n\\n function harvest() external;\\n\\n function harvest(address _strategyAddr) external;\\n\\n function priceUSDMint(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n function priceUSDRedeem(string calldata symbol)\\n external\\n view\\n returns (uint256);\\n\\n // VaultCore.sol\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amount,\\n uint256 _minimumOusdAmount\\n ) external;\\n\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount) external;\\n\\n function redeemAll(uint256 _minimumUnitAmount) external;\\n\\n function allocate() external;\\n\\n function reallocate(\\n address _strategyFromAddress,\\n address _strategyToAddress,\\n address[] calldata _assets,\\n uint256[] calldata _amounts\\n ) external;\\n\\n function rebase() external;\\n\\n function totalValue() external view returns (uint256 value);\\n\\n function checkBalance() external view returns (uint256);\\n\\n function checkBalance(address _asset) external view returns (uint256);\\n\\n function calculateRedeemOutputs(uint256 _amount)\\n external\\n view\\n returns (uint256[] memory);\\n\\n function getAssetCount() external view returns (uint256);\\n\\n function getAllAssets() external view returns (address[] memory);\\n\\n function getStrategyCount() external view returns (uint256);\\n\\n function isSupportedAsset(address _asset) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x84271ee5504677f7ad8b808df40d16704d5e2b83a9cdb897208d8c7b3e6cb8bb\"},\"contracts/token/OUSD.sol\":{\"content\":\"pragma solidity 0.5.11;\\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/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nimport {\\n InitializableERC20Detailed\\n} 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 TotalSupplyUpdated(\\n uint256 totalSupply,\\n uint256 rebasingCredits,\\n uint256 rebasingCreditsPerToken\\n );\\n\\n enum RebaseOptions { NotSet, OptOut, OptIn }\\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 public rebasingCredits;\\n uint256 public 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\\n function initialize(\\n string calldata _nameArg,\\n string calldata _symbolArg,\\n address _vaultAddress\\n ) external onlyGovernor initializer {\\n InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);\\n rebasingCreditsPerToken = 1e18;\\n vaultAddress = _vaultAddress;\\n }\\n\\n /**\\n * @dev Verifies that the caller is the Savings Manager 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 returns (uint256) {\\n return _totalSupply;\\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) public view returns (uint256) {\\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 * @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 return (_creditBalances[_account], _creditsPerToken(_account));\\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) public returns (bool) {\\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 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 an owner has allowed to a _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 returns (uint256)\\n {\\n return _allowances[_owner][_spender];\\n }\\n\\n /**\\n * @dev Approve the passed address to spend the specified _amount of tokens on behalf of\\n * msg.sender. This method is included for ERC20 compatibility.\\n * increaseAllowance and decreaseAllowance should be used instead.\\n * Changing an allowance with this method brings the risk that someone may transfer both\\n * the old and the new allowance - if they are both greater than zero - if a transfer\\n * transaction is mined before the later approve() call is mined.\\n *\\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) public returns (bool) {\\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 a _spender.\\n * This method should be used instead of approve() to avoid the double approval vulnerability\\n * 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 a _spender.\\n * @param _spender The address which will spend the funds.\\n * @param _subtractedValue The _amount of tokens to decrease the allowance 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 // 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(_creditBalances[_account]);\\n }\\n }\\n\\n /**\\n * @dev Add a contract address to the non rebasing exception list. I.e. the\\n * address's balance will be part of rebases so the account will be exposed\\n * to upside and downside.\\n */\\n function rebaseOptIn() public nonReentrant {\\n require(_isNonRebasingAccount(msg.sender), \\\"Account has not opted out\\\");\\n\\n // Convert balance into the same amount at the current exchange rate\\n uint256 newCreditBalance = _creditBalances[msg.sender]\\n .mul(rebasingCreditsPerToken)\\n .div(_creditsPerToken(msg.sender));\\n\\n // Decreasing non rebasing supply\\n nonRebasingSupply = nonRebasingSupply.sub(balanceOf(msg.sender));\\n\\n _creditBalances[msg.sender] = newCreditBalance;\\n\\n // Increase rebasing credits, totalSupply remains unchanged so no\\n // adjustment necessary\\n rebasingCredits = rebasingCredits.add(_creditBalances[msg.sender]);\\n\\n rebaseState[msg.sender] = RebaseOptions.OptIn;\\n\\n // Delete any fixed credits per token\\n delete nonRebasingCreditsPerToken[msg.sender];\\n }\\n\\n /**\\n * @dev Remove a contract address to the non rebasing exception list.\\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 }\\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 * @return uint256 representing the new total supply.\\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 TotalSupplyUpdated(\\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 TotalSupplyUpdated(\\n _totalSupply,\\n rebasingCredits,\\n rebasingCreditsPerToken\\n );\\n }\\n}\\n\",\"keccak256\":\"0xea89a8b152b363982ba8db340b1e20c3194b2e75a06630cbbf43e3c50fff61a4\"},\"contracts/utils/Helpers.sol\":{\"content\":\"pragma solidity 0.5.11;\\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\":\"0xd2ca92e0af883dc1aec5b22caced274e59829e0e30a9e955dcc48b8d921f5cdc\"},\"contracts/utils/InitializableERC20Detailed.sol\":{\"content\":\"pragma solidity 0.5.11;\\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 */\\ncontract 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 * @dev Returns the name of the token.\\n */\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev 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 * @dev 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\":\"0x7919369d0f3bd74b4f0ee78a682afe43f91b186cdd0708e303068e4feeb29007\"},\"contracts/utils/StableMath.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\nimport { SafeMath } from \\\"@openzeppelin/contracts/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 adjustment Amount to adjust by e.g. scaleBy(1e18, -1) == 1e17\\n */\\n function scaleBy(uint256 x, int8 adjustment)\\n internal\\n pure\\n returns (uint256)\\n {\\n if (adjustment > 0) {\\n x = x.mul(10**uint256(adjustment));\\n } else if (adjustment < 0) {\\n x = x.div(10**uint256(adjustment * -1));\\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 9e38 / 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\":\"0xa77fccf850feb6d54ba3a6530f92554caef8a67a1ceb573d4f8a5d1bf64ff9d2\"},\"contracts/vault/VaultCore.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD Vault Contract\\n * @notice The Vault contract stores assets. On a deposit, OUSD will be minted\\n and sent to the depositor. On a withdrawal, OUSD will be burned and\\n assets will be sent to the withdrawer. The Vault accepts deposits of\\n interest form yield bearing strategies which will modify the supply\\n of OUSD.\\n * @author Origin Protocol Inc\\n */\\n\\nimport \\\"./VaultStorage.sol\\\";\\nimport { IMinMaxOracle } from \\\"../interfaces/IMinMaxOracle.sol\\\";\\nimport { IVault } from \\\"../interfaces/IVault.sol\\\";\\n\\ncontract VaultCore is VaultStorage {\\n uint256 constant MAX_UINT = 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 /**\\n * @dev Deposit a supported asset and mint OUSD.\\n * @param _asset Address of the asset being deposited\\n * @param _amount Amount of the asset being deposited\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mint(\\n address _asset,\\n uint256 _amount,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(assets[_asset].isSupported, \\\"Asset is not supported\\\");\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 price = IMinMaxOracle(priceProvider).priceMin(\\n Helpers.getSymbol(_asset)\\n );\\n if (price > 1e8) {\\n price = 1e8;\\n }\\n uint256 assetDecimals = Helpers.getDecimals(_asset);\\n uint256 unitAdjustedDeposit = _amount.scaleBy(int8(18 - assetDecimals));\\n uint256 priceAdjustedDeposit = _amount.mulTruncateScale(\\n price.scaleBy(int8(10)), // 18-8 because oracles have 8 decimals precision\\n 10**assetDecimals\\n );\\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 (unitAdjustedDeposit >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n // Mint matching OUSD\\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 (unitAdjustedDeposit >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Mint for multiple assets in the same call.\\n * @param _assets Addresses of assets being deposited\\n * @param _amounts Amount of each asset at the same index in the _assets\\n * to deposit.\\n * @param _minimumOusdAmount Minimum OUSD to mint\\n */\\n function mintMultiple(\\n address[] calldata _assets,\\n uint256[] calldata _amounts,\\n uint256 _minimumOusdAmount\\n ) external whenNotCapitalPaused nonReentrant {\\n require(_assets.length == _amounts.length, \\\"Parameter length mismatch\\\");\\n\\n uint256 unitAdjustedTotal = 0;\\n uint256 priceAdjustedTotal = 0;\\n uint256[] memory assetPrices = _getAssetPrices(false);\\n for (uint256 j = 0; j < _assets.length; j++) {\\n // In memoriam\\n require(assets[_assets[j]].isSupported, \\\"Asset is not supported\\\");\\n require(_amounts[j] > 0, \\\"Amount must be greater than 0\\\");\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (_assets[j] == allAssets[i]) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n uint256 price = assetPrices[i];\\n if (price > 1e18) {\\n price = 1e18;\\n }\\n unitAdjustedTotal = unitAdjustedTotal.add(\\n _amounts[j].scaleBy(int8(18 - assetDecimals))\\n );\\n priceAdjustedTotal = priceAdjustedTotal.add(\\n _amounts[j].mulTruncateScale(price, 10**assetDecimals)\\n );\\n }\\n }\\n }\\n\\n if (_minimumOusdAmount > 0) {\\n require(\\n priceAdjustedTotal >= _minimumOusdAmount,\\n \\\"Mint amount lower than minimum\\\"\\n );\\n }\\n\\n emit Mint(msg.sender, priceAdjustedTotal);\\n\\n // Rebase must happen before any transfers occur.\\n if (unitAdjustedTotal >= rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n\\n oUSD.mint(msg.sender, priceAdjustedTotal);\\n\\n for (uint256 i = 0; i < _assets.length; i++) {\\n IERC20 asset = IERC20(_assets[i]);\\n asset.safeTransferFrom(msg.sender, address(this), _amounts[i]);\\n }\\n\\n if (unitAdjustedTotal >= autoAllocateThreshold) {\\n _allocate();\\n }\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeem(uint256 _amount, uint256 _minimumUnitAmount)\\n public\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(_amount, _minimumUnitAmount);\\n }\\n\\n /**\\n * @dev Withdraw a supported asset and burn OUSD.\\n * @param _amount Amount of OUSD to burn\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function _redeem(uint256 _amount, uint256 _minimumUnitAmount) internal {\\n require(_amount > 0, \\\"Amount must be greater than 0\\\");\\n\\n uint256 _totalSupply = oUSD.totalSupply();\\n uint256 _backingValue = _totalValue();\\n\\n if (maxSupplyDiff > 0) {\\n // Allow a max difference of maxSupplyDiff% between\\n // backing assets value and OUSD total supply\\n uint256 diff = _totalSupply.divPrecisely(_backingValue);\\n\\n require(\\n (diff > 1e18 ? diff.sub(1e18) : uint256(1e18).sub(diff)) <=\\n maxSupplyDiff,\\n \\\"Backing supply liquidity error\\\"\\n );\\n }\\n\\n emit Redeem(msg.sender, _amount);\\n\\n // Calculate redemption outputs\\n uint256[] memory outputs = _calculateRedeemOutputs(_amount);\\n // Send outputs\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n if (outputs[i] == 0) continue;\\n\\n IERC20 asset = IERC20(allAssets[i]);\\n\\n if (asset.balanceOf(address(this)) >= outputs[i]) {\\n // Use Vault funds first if sufficient\\n asset.safeTransfer(msg.sender, outputs[i]);\\n } else {\\n address strategyAddr = assetDefaultStrategies[allAssets[i]];\\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, allAssets[i], 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 uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n unitTotal = unitTotal.add(\\n outputs[i].scaleBy(int8(18 - assetDecimals))\\n );\\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 if (_amount > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n }\\n\\n /**\\n * @notice Withdraw a supported asset and burn all OUSD.\\n * @param _minimumUnitAmount Minimum stablecoin units to receive in return\\n */\\n function redeemAll(uint256 _minimumUnitAmount)\\n external\\n whenNotCapitalPaused\\n nonReentrant\\n {\\n // Unfortunately we have to do balanceOf twice, the rebase may change\\n // the account balance\\n if (oUSD.balanceOf(msg.sender) > rebaseThreshold && !rebasePaused) {\\n _rebase();\\n }\\n _redeem(oUSD.balanceOf(msg.sender), _minimumUnitAmount);\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\n * @dev Allocate unallocated funds on Vault to strategies.\\n **/\\n function allocate() public whenNotCapitalPaused nonReentrant {\\n _allocate();\\n }\\n\\n /**\\n * @notice Allocate unallocated funds on Vault to strategies.\\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.add(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).sub(vaultBuffer);\\n } else {\\n vaultBufferModifier = vaultBuffer.mul(calculatedTotalValue).div(\\n vaultValue\\n );\\n if (1e18 > vaultBufferModifier) {\\n // E.g. 1e18 - (1e17 * 10e18)/5e18 = 8e17\\n // (5e18 * 8e17) / 1e18 = 4e18 allocated from Vault\\n vaultBufferModifier = uint256(1e18).sub(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 the the appropriate\\n // strategy\\n for (uint256 i = 0; i < allAssets.length; 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[address(\\n 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 }\\n }\\n\\n // Harvest for all reward tokens above reward liquidation threshold\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n address rewardTokenAddress = strategy.rewardTokenAddress();\\n if (rewardTokenAddress != address(0)) {\\n uint256 liquidationThreshold = strategy\\n .rewardLiquidationThreshold();\\n if (liquidationThreshold == 0) {\\n // No threshold set, always harvest from strategy\\n IVault(address(this)).harvest(allStrategies[i]);\\n } else {\\n // Check balance against liquidation threshold\\n // Note some strategies don't hold the reward token balance\\n // on their contract so the liquidation threshold should be\\n // set to 0\\n IERC20 rewardToken = IERC20(rewardTokenAddress);\\n uint256 rewardTokenAmount = rewardToken.balanceOf(\\n allStrategies[i]\\n );\\n if (rewardTokenAmount >= liquidationThreshold) {\\n IVault(address(this)).harvest(allStrategies[i]);\\n }\\n }\\n }\\n }\\n }\\n\\n /**\\n * @dev Calculate the total value of assets held by the Vault and all\\n * strategies and update the supply of OUSD.\\n */\\n function rebase() public whenNotRebasePaused 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 OUSD, optionaly sending a\\n * portion of the yield to the trustee.\\n */\\n function _rebase() internal whenNotRebasePaused {\\n uint256 ousdSupply = oUSD.totalSupply();\\n if (ousdSupply == 0) {\\n return;\\n }\\n uint256 vaultValue = _totalValue();\\n\\n // Yield fee collection\\n address _trusteeAddress = trusteeAddress; // gas savings\\n if (_trusteeAddress != address(0) && (vaultValue > ousdSupply)) {\\n uint256 yield = vaultValue.sub(ousdSupply);\\n uint256 fee = yield.mul(trusteeFeeBps).div(10000);\\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 OUSD supply upwards\\n ousdSupply = oUSD.totalSupply(); // Final check should use latest value\\n if (vaultValue > ousdSupply) {\\n oUSD.changeSupply(vaultValue);\\n }\\n }\\n\\n /**\\n * @dev Determine the total value of assets held by the vault and its\\n * strategies.\\n * @return uint256 value Total value in USD (1e18)\\n */\\n function totalValue() external view 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 uint256 value Total value in USD (1e18)\\n */\\n function _totalValue() internal view returns (uint256 value) {\\n return _totalValueInVault().add(_totalValueInStrategies());\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Vault.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInVault() internal view returns (uint256 value) {\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n IERC20 asset = IERC20(allAssets[y]);\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n uint256 balance = asset.balanceOf(address(this));\\n if (balance > 0) {\\n value = value.add(balance.scaleBy(int8(18 - assetDecimals)));\\n }\\n }\\n }\\n\\n /**\\n * @dev Internal to calculate total value of all assets held in Strategies.\\n * @return uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategies() internal view returns (uint256 value) {\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n value = value.add(_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 uint256 Total value in ETH (1e18)\\n */\\n function _totalValueInStrategy(address _strategyAddr)\\n internal\\n view\\n returns (uint256 value)\\n {\\n IStrategy strategy = IStrategy(_strategyAddr);\\n for (uint256 y = 0; y < allAssets.length; y++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[y]);\\n if (strategy.supportsAsset(allAssets[y])) {\\n uint256 balance = strategy.checkBalance(allAssets[y]);\\n if (balance > 0) {\\n value = value.add(\\n balance.scaleBy(int8(18 - assetDecimals))\\n );\\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 uint256 Balance of asset in decimals of asset\\n */\\n function _checkBalance(address _asset)\\n internal\\n view\\n returns (uint256 balance)\\n {\\n IERC20 asset = IERC20(_asset);\\n balance = asset.balanceOf(address(this));\\n for (uint256 i = 0; i < allStrategies.length; i++) {\\n IStrategy strategy = IStrategy(allStrategies[i]);\\n if (strategy.supportsAsset(_asset)) {\\n balance = balance.add(strategy.checkBalance(_asset));\\n }\\n }\\n }\\n\\n /**\\n * @notice Get the balance of all assets held in Vault and all strategies.\\n * @return uint256 Balance of all assets (1e18)\\n */\\n function _checkBalance() internal view returns (uint256 balance) {\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 assetDecimals = Helpers.getDecimals(allAssets[i]);\\n balance = balance.add(\\n _checkBalance(allAssets[i]).scaleBy(int8(18 - assetDecimals))\\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 * @notice Calculate the outputs for a redeem function, i.e. the mix of\\n * coins that will be returned.\\n * @return 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 = getAssetCount();\\n uint256[] memory assetPrices = _getAssetPrices(true);\\n uint256[] memory assetBalances = new uint256[](assetCount);\\n uint256[] memory assetDecimals = new uint256[](assetCount);\\n uint256 totalBalance = 0;\\n uint256 totalOutputRatio = 0;\\n outputs = new uint256[](assetCount);\\n\\n // Calculate redeem fee\\n if (redeemFeeBps > 0) {\\n uint256 redeemFee = _amount.mul(redeemFeeBps).div(10000);\\n _amount = _amount.sub(redeemFee);\\n }\\n\\n // Calculate assets balances and decimals once,\\n // for a large gas savings.\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 balance = _checkBalance(allAssets[i]);\\n uint256 decimals = Helpers.getDecimals(allAssets[i]);\\n assetBalances[i] = balance;\\n assetDecimals[i] = decimals;\\n totalBalance = totalBalance.add(\\n balance.scaleBy(int8(18 - decimals))\\n );\\n }\\n // Calculate totalOutputRatio\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n uint256 price = assetPrices[i];\\n // Never give out more than one\\n // stablecoin per dollar of OUSD\\n if (price < 1e18) {\\n price = 1e18;\\n }\\n uint256 ratio = assetBalances[i]\\n .scaleBy(int8(18 - assetDecimals[i]))\\n .mul(price)\\n .div(totalBalance);\\n totalOutputRatio = totalOutputRatio.add(ratio);\\n }\\n // Calculate final outputs\\n uint256 factor = _amount.divPrecisely(totalOutputRatio);\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n outputs[i] = assetBalances[i].mul(factor).div(totalBalance);\\n }\\n }\\n\\n /**\\n * @notice Get an array of the supported asset prices in USD.\\n * @return uint256[] Array of asset prices in USD (1e18)\\n */\\n function _getAssetPrices(bool useMax)\\n internal\\n view\\n returns (uint256[] memory assetPrices)\\n {\\n assetPrices = new uint256[](getAssetCount());\\n\\n IMinMaxOracle oracle = IMinMaxOracle(priceProvider);\\n // Price from Oracle is returned with 8 decimals\\n // _amount is in assetDecimals\\n\\n for (uint256 i = 0; i < allAssets.length; i++) {\\n string memory symbol = Helpers.getSymbol(allAssets[i]);\\n // Get all the USD prices of the asset in 1e18\\n if (useMax) {\\n assetPrices[i] = oracle.priceMax(symbol).scaleBy(int8(18 - 8));\\n } else {\\n assetPrices[i] = oracle.priceMin(symbol).scaleBy(int8(18 - 8));\\n }\\n }\\n }\\n\\n /***************************************\\n Utils\\n ****************************************/\\n\\n /**\\n * @dev Return the number of assets suppported by the Vault.\\n */\\n function getAssetCount() public view returns (uint256) {\\n return allAssets.length;\\n }\\n\\n /**\\n * @dev Return all asset addresses in order\\n */\\n function getAllAssets() external view returns (address[] memory) {\\n return allAssets;\\n }\\n\\n /**\\n * @dev Return the number of strategies active on the Vault.\\n */\\n function getStrategyCount() external view returns (uint256) {\\n return allStrategies.length;\\n }\\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 function() external payable {\\n bytes32 slot = adminImplPosition;\\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(gas, sload(slot), 0, calldatasize, 0, 0)\\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\",\"keccak256\":\"0x9af2d88c824d11589927a4f7c1f60157ead5ca26352a4171139ece27a3b5b22d\"},\"contracts/vault/VaultStorage.sol\":{\"content\":\"pragma solidity 0.5.11;\\n\\n/**\\n * @title OUSD 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/SafeERC20.sol\\\";\\nimport { SafeMath } from \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/upgrades/contracts/Initializable.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 \\\"../utils/Helpers.sol\\\";\\nimport { StableMath } from \\\"../utils/StableMath.sol\\\";\\n\\ncontract VaultStorage is Initializable, Governable {\\n using SafeMath for uint256;\\n using StableMath for uint256;\\n using SafeMath for int256;\\n using SafeERC20 for IERC20;\\n\\n event AssetSupported(address _asset);\\n event AssetDefaultStrategyUpdated(address _asset, address _strategy);\\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 RedeemFeeUpdated(uint256 _redeemFeeBps);\\n event PriceProviderUpdated(address _priceProvider);\\n event AllocateThresholdUpdated(uint256 _threshold);\\n event RebaseThresholdUpdated(uint256 _threshold);\\n event UniswapUpdated(address _address);\\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\\n // Assets supported by the Vault, i.e. Stablecoins\\n struct Asset {\\n bool isSupported;\\n }\\n mapping(address => Asset) assets;\\n address[] allAssets;\\n\\n // Strategies approved for use by the Vault\\n struct Strategy {\\n bool isSupported;\\n uint256 _deprecated; // Deprecated storage slot\\n }\\n mapping(address => Strategy) strategies;\\n address[] allStrategies;\\n\\n // Address of the Oracle price provider contract\\n address public priceProvider;\\n // Pausing bools\\n bool public rebasePaused = false;\\n bool public capitalPaused = true;\\n // Redemption fee in basis points\\n uint256 public redeemFeeBps;\\n // Buffer of assets to keep in Vault to handle (most) withdrawals\\n uint256 public vaultBuffer;\\n // Mints over this amount automatically allocate funds. 18 decimals.\\n uint256 public autoAllocateThreshold;\\n // Mints over this amount automatically rebase. 18 decimals.\\n uint256 public rebaseThreshold;\\n\\n OUSD oUSD;\\n\\n //keccak256(\\\"OUSD.vault.governor.admin.impl\\\");\\n bytes32 constant adminImplPosition = 0xa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9;\\n\\n // Address of the contract responsible for post rebase syncs with AMMs\\n address private _deprecated_rebaseHooksAddr = address(0);\\n\\n // Address of Uniswap\\n address public uniswapAddr = address(0);\\n\\n // Address of the Strategist\\n address public strategistAddr = address(0);\\n\\n // Mapping of asset address to the Strategy that they should automatically\\n // be allocated to\\n mapping(address => address) public assetDefaultStrategies;\\n\\n uint256 public maxSupplyDiff;\\n\\n // Trustee address that can collect a percentage of yield\\n address public trusteeAddress;\\n\\n // Amount of yield collected in basis points\\n uint256 public trusteeFeeBps;\\n\\n /**\\n * @dev 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 assembly {\\n sstore(position, newImpl)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02d224b70c086a3df5cf22792721aed5f278ddf4bc7b98b67ac9c38c767760a0\"}},\"version\":1}", + "bytecode": "0x60806040526037805461ffff60a01b19167501000000000000000000000000000000000000000000179055603d80546001600160a01b0319908116909155603e805482169055603f8054909116905562000062336001600160e01b03620000bb16565b620000756001600160e01b03620000ce16565b6001600160a01b031660006001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3620000e2565b600080516020620039e783398151915255565b600080516020620039e78339815191525490565b6138f580620000f26000396000f3fe6080604052600436106101d85760003560e01c80637136a7a611610102578063af14052c11610095578063d4c3eea011610064578063d4c3eea0146105d0578063e6cc5432146105e5578063f0efb4c7146105fa578063fc0cfeee146106c9576101d8565b8063af14052c1461055e578063b888879e14610573578063c7af335214610588578063d38bfff41461059d576101d8565b80639fa1826e116100d15780639fa1826e146104ec578063a0aead4d14610501578063a403e4d514610516578063abaa991614610549576101d8565b80637136a7a61461044a5780637cbc2373146104745780638e510b52146104a45780639be918e6146104b9576101d8565b806331e19cfa1161017a578063570d8e1d11610149578063570d8e1d146103c35780635d36b190146103d85780635f515226146103ed57806367bd7ba314610420576101d8565b806331e19cfa1461035b57806349c1d54d1461037057806352d38e5d1461038557806353ca9f241461039a576101d8565b8063156e29f6116101b6578063156e29f61461028b5780631edfe3da146102cc578063207134b0146102e15780632acada4d146102f6576101d8565b806309f6442c1461021e5780630c340a2414610245578063128a8b0514610276575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610219573d6000f35b3d6000fd5b34801561022a57600080fd5b506102336106fc565b60408051918252519081900360200190f35b34801561025157600080fd5b5061025a610702565b604080516001600160a01b039092168252519081900360200190f35b34801561028257600080fd5b5061025a610711565b34801561029757600080fd5b506102ca600480360360608110156102ae57600080fd5b506001600160a01b038135169060208101359060400135610720565b005b3480156102d857600080fd5b50610233610b33565b3480156102ed57600080fd5b50610233610b39565b34801561030257600080fd5b5061030b610b3f565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561034757818101518382015260200161032f565b505050509050019250505060405180910390f35b34801561036757600080fd5b50610233610ba1565b34801561037c57600080fd5b5061025a610ba7565b34801561039157600080fd5b50610233610bb6565b3480156103a657600080fd5b506103af610bbc565b604080519115158252519081900360200190f35b3480156103cf57600080fd5b5061025a610bcc565b3480156103e457600080fd5b506102ca610bdb565b3480156103f957600080fd5b506102336004803603602081101561041057600080fd5b50356001600160a01b0316610c3d565b34801561042c57600080fd5b5061030b6004803603602081101561044357600080fd5b5035610c4e565b34801561045657600080fd5b506102ca6004803603602081101561046d57600080fd5b5035610c59565b34801561048057600080fd5b506102ca6004803603604081101561049757600080fd5b5080359060200135610e29565b3480156104b057600080fd5b50610233610f10565b3480156104c557600080fd5b506103af600480360360208110156104dc57600080fd5b50356001600160a01b0316610f16565b3480156104f857600080fd5b50610233610f34565b34801561050d57600080fd5b50610233610f3a565b34801561052257600080fd5b5061025a6004803603602081101561053957600080fd5b50356001600160a01b0316610f40565b34801561055557600080fd5b506102ca610f5b565b34801561056a57600080fd5b506102ca611016565b34801561057f57600080fd5b5061025a6110cb565b34801561059457600080fd5b506103af6110da565b3480156105a957600080fd5b506102ca600480360360208110156105c057600080fd5b50356001600160a01b03166110fd565b3480156105dc57600080fd5b506102336111a9565b3480156105f157600080fd5b506103af6111b3565b34801561060657600080fd5b506102ca6004803603606081101561061d57600080fd5b81019060208101813564010000000081111561063857600080fd5b82018360208201111561064a57600080fd5b8035906020019184602083028401116401000000008311171561066c57600080fd5b91939092909160208101903564010000000081111561068a57600080fd5b82018360208201111561069c57600080fd5b803590602001918460208302840111640100000000831117156106be57600080fd5b9193509150356111c3565b3480156106d557600080fd5b506102ca600480360360208110156106ec57600080fd5b50356001600160a01b03166116be565b60385481565b600061070c61177f565b905090565b603e546001600160a01b031681565b603754600160a81b900460ff1615610770576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156107c8576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff16610832576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610887576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf06108a4886117a4565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108f05781810151838201526020016108d8565b50505050905090810190601f16801561091d5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d602081101561096457600080fd5b505190506305f5e10081111561097b57506305f5e1005b6000610986876118d5565b9050600061099e87601284900363ffffffff61198f16565b905060006109c86109b685600a63ffffffff61198f16565b8990600a86900a63ffffffff6119e916565b90508615610a255786811015610a25576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a7c5750603754600160a01b900460ff16155b15610a8957610a89611a17565b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610adc57600080fd5b505af1158015610af0573d6000803e3d6000fd5b508b9250610b129150506001600160a01b03821633308c63ffffffff611d3e16565b603a548310610b2357610b23611d9e565b5050505050600182555050505050565b60395481565b60435481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b9757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b79575b5050505050905090565b60365490565b6042546001600160a01b031681565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610be36122c1565b6001600160a01b0316336001600160a01b031614610c325760405162461bcd60e51b81526004018080602001828103825260308152602001806138916030913960400191505060405180910390fd5b610c3b336122e6565b565b6000610c4882612394565b92915050565b6060610c4882612555565b603754600160a81b900460ff1615610ca9576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610d01576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d5357600080fd5b505afa158015610d67573d6000803e3d6000fd5b505050506040513d6020811015610d7d57600080fd5b5051118015610d965750603754600160a01b900460ff16155b15610da357610da3611a17565b603c54604080516370a0823160e01b81523360048201529051610e21926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610def57600080fd5b505afa158015610e03573d6000803e3d6000fd5b505050506040513d6020811015610e1957600080fd5b505184612816565b506001905550565b603754600160a81b900460ff1615610e79576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610ed1576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ef05750603754600160a01b900460ff16155b15610efd57610efd611a17565b610f078484612816565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610fab576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415611003576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611d9e565b5060019055565b603754600160a01b900460ff1615611067576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156110bf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611a17565b6037546001600160a01b031681565b60006110e461177f565b6001600160a01b0316336001600160a01b031614905090565b6111056110da565b611156576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61115f81612dc0565b806001600160a01b031661117161177f565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b600061070c612de4565b603754600160a81b900460ff1681565b603754600160a81b900460ff1615611213576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b78339815191528054600281141561126b576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282558584146112c3576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b60008060606112d182612e05565b905060005b8981101561150a57603360008c8c848181106112ee57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661135e576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061136c57fe5b90506020020135116113c5576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b60345481101561150157603481815481106113df57fe5b6000918252602090912001546001600160a01b03168c8c8481811061140057fe5b905060200201356001600160a01b03166001600160a01b031614156114f957600061144b6034838154811061143157fe5b6000918252602090912001546001600160a01b03166118d5565b9050600084838151811061145b57fe5b60200260200101519050670de0b6b3a76400008111156114805750670de0b6b3a76400005b6114b86114ab836012038e8e8881811061149657fe5b9050602002013561198f90919063ffffffff16565b889063ffffffff61300b16565b96506114f46114e78284600a0a8f8f898181106114d157fe5b905060200201356119e99092919063ffffffff16565b879063ffffffff61300b16565b955050505b6001016113c8565b506001016112d6565b5085156115665785821015611566576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b5483101580156115bd5750603754600160a01b900460ff16155b156115ca576115ca611a17565b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b15801561161d57600080fd5b505af1158015611631573d6000803e3d6000fd5b506000925050505b8981101561169c5760008b8b8381811061164f57fe5b905060200201356001600160a01b0316905061169333308c8c8681811061167257fe5b90506020020135846001600160a01b0316611d3e909392919063ffffffff16565b50600101611639565b50603a5483106116ae576116ae611d9e565b5050506001825550505050505050565b6116c66110da565b611717576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b6117208161306c565b61175b5760405162461bcd60e51b81526004018080602001828103825260248152602001806137d76024913960400191505060405180910390fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561181d57600080fd5b810190808051604051939291908464010000000082111561183d57600080fd5b90830190602082018581111561185257600080fd5b825164010000000081118282018810171561186c57600080fd5b82525081516020918201929091019080838360005b83811015611899578181015183820152602001611881565b50505050905090810190601f1680156118c65780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561191157600080fd5b505afa158015611925573d6000803e3d6000fd5b505050506040513d602081101561193b57600080fd5b505160ff16905060048110801590611954575060128111155b610c485760405162461bcd60e51b81526004018080602001828103825260298152602001806137fb6029913960400191505060405180910390fd5b6000808260000b13156119ba576119b383600084900b600a0a63ffffffff6130a816565b92506119e2565b60008260000b12156119e2576119df836000848103900b600a0a63ffffffff61310116565b92505b5090919050565b6000806119fc858563ffffffff6130a816565b9050611a0e818463ffffffff61310116565b95945050505050565b603754600160a01b900460ff1615611a68576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611aad57600080fd5b505afa158015611ac1573d6000803e3d6000fd5b505050506040513d6020811015611ad757600080fd5b5051905080611ae65750610c3b565b6000611af0612de4565b6042549091506001600160a01b03168015801590611b0d57508282115b15611c4f576000611b24838563ffffffff61314316565b90506000611b4f612710611b43604354856130a890919063ffffffff16565b9063ffffffff61310116565b9050808211611b8f5760405162461bcd60e51b81526004018080602001828103825260228152602001806138456022913960400191505060405180910390fd5b8015611c0357603c54604080516340c10f1960e01b81526001600160a01b03868116600483015260248201859052915191909216916340c10f1991604480830192600092919082900301818387803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b505050505b604080516001600160a01b03851681526020810184905280820183905290517f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809181900360600190a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9d57600080fd5b505afa158015611cb1573d6000803e3d6000fd5b505050506040513d6020811015611cc757600080fd5b5051925082821115611d3957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611d2057600080fd5b505af1158015611d34573d6000803e3d6000fd5b505050505b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611d98908590613185565b50505050565b6000611da861333d565b905080611db55750610c3b565b6000611dbf61342d565b90506000611dd3838363ffffffff61300b16565b9050600082611dff57603954611df890670de0b6b3a76400009063ffffffff61314316565b9050611e4b565b611e1884611b43846039546130a890919063ffffffff16565b905080670de0b6b3a76400001115611e4257611df8670de0b6b3a76400008263ffffffff61314316565b50505050610c3b565b80611e595750505050610c3b565b60005b603454811015611fe857600060348281548110611e7557fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611ec857600080fd5b505afa158015611edc573d6000803e3d6000fd5b505050506040513d6020811015611ef257600080fd5b5051905080611f02575050611fe0565b6000611f14828663ffffffff61347f16565b6001600160a01b03808516600090815260406020819052902054919250168015801590611f415750600082115b15611fdb5780611f616001600160a01b038616828563ffffffff61349416565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611fc157600080fd5b505af1158015611fd5573d6000803e3d6000fd5b50505050505b505050505b600101611e5c565b5060005b6036548110156122ba5760006036828154811061200557fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b15801561205257600080fd5b505afa158015612066573d6000803e3d6000fd5b505050506040513d602081101561207c57600080fd5b505190506001600160a01b038116156122b0576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b1580156120ca57600080fd5b505afa1580156120de573d6000803e3d6000fd5b505050506040513d60208110156120f457600080fd5b505190508061218357306001600160a01b0316630e5c011e6036868154811061211957fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561216657600080fd5b505af115801561217a573d6000803e3d6000fd5b505050506122ae565b60008290506000816001600160a01b03166370a08231603688815481106121a657fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156121f457600080fd5b505afa158015612208573d6000803e3d6000fd5b505050506040513d602081101561221e57600080fd5b505190508281106122ab57306001600160a01b0316630e5c011e6036888154811061224557fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561229257600080fd5b505af11580156122a6573d6000803e3d6000fd5b505050505b50505b505b5050600101611fec565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b038116612341576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661235361177f565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3612391816134e6565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b1580156123df57600080fd5b505afa1580156123f3573d6000803e3d6000fd5b505050506040513d602081101561240957600080fd5b5051915060005b60365481101561254e5760006036828154811061242957fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b15801561247f57600080fd5b505afa158015612493573d6000803e3d6000fd5b505050506040513d60208110156124a957600080fd5b50511561254557612542816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561250957600080fd5b505afa15801561251d573d6000803e3d6000fd5b505050506040513d602081101561253357600080fd5b5051859063ffffffff61300b16565b93505b50600101612410565b5050919050565b60606000612561610f3a565b9050606061256f6001612e05565b905060608260405190808252806020026020018201604052801561259d578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156125cc578160200160208202803883390190505b5060408051868152602080880282010190915290915060009081908680156125fe578160200160208202803883390190505b506038549097501561263d576000612627612710611b436038548c6130a890919063ffffffff16565b9050612639898263ffffffff61314316565b9850505b60005b6034548110156126ed5760006126766034838154811061265c57fe5b6000918252602090912001546001600160a01b0316612394565b9050600061268a6034848154811061143157fe5b90508187848151811061269957fe5b602002602001018181525050808684815181106126b257fe5b60209081029190910101526126e16126d483601284900363ffffffff61198f16565b869063ffffffff61300b16565b94505050600101612640565b5060005b60345481101561279e57600086828151811061270957fe5b60200260200101519050670de0b6b3a764000081101561272e5750670de0b6b3a76400005b600061278085611b43846127748a888151811061274757fe5b60200260200101516012038c898151811061275e57fe5b602002602001015161198f90919063ffffffff16565b9063ffffffff6130a816565b9050612792848263ffffffff61300b16565b935050506001016126f1565b5060006127b1898363ffffffff61350a16565b905060005b603454811015612809576127ea84611b43848985815181106127d457fe5b60200260200101516130a890919063ffffffff16565b8982815181106127f657fe5b60209081029190910101526001016127b6565b5050505050505050919050565b6000821161286b576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156128b057600080fd5b505afa1580156128c4573d6000803e3d6000fd5b505050506040513d60208110156128da57600080fd5b5051905060006128e8612de4565b604154909150156129a3576000612905838363ffffffff61350a16565b9050604154670de0b6b3a7640000821161293657612931670de0b6b3a76400008363ffffffff61314316565b61294e565b61294e82670de0b6b3a764000063ffffffff61314316565b11156129a1576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a160606129e985612555565b905060005b603454811015612c7f57818181518110612a0457fe5b602002602001015160001415612a1957612c77565b600060348281548110612a2857fe5b60009182526020909120015483516001600160a01b039091169150839083908110612a4f57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612aad57600080fd5b505afa158015612ac1573d6000803e3d6000fd5b505050506040513d6020811015612ad757600080fd5b505110612b1457612b0f33848481518110612aee57fe5b6020026020010151836001600160a01b03166134949092919063ffffffff16565b612c75565b60006040600060348581548110612b2757fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612c34576000819050806001600160a01b031663d9caed123360348781548110612b7c57fe5b9060005260206000200160009054906101000a90046001600160a01b0316888881518110612ba657fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612c1657600080fd5b505af1158015612c2a573d6000803e3d6000fd5b5050505050612c73565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b6001016129ee565b508315612d2d576000805b8251811015612cd5576000612ca56034838154811061143157fe5b9050612cca612cbd8260120386858151811061275e57fe5b849063ffffffff61300b16565b925050600101612c8a565b5084811015612d2b576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612d8057600080fd5b505af1158015612d94573d6000803e3d6000fd5b50505050603b5485118015612db35750603754600160a01b900460ff16155b156122ba576122ba611a17565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b600061070c612df161342d565b612df961333d565b9063ffffffff61300b16565b6060612e0f610f3a565b604051908082528060200260200182016040528015612e38578160200160208202803883390190505b506037549091506001600160a01b031660005b60345481101561254e576060612e8160348381548110612e6757fe5b6000918252602090912001546001600160a01b03166117a4565b90508415612f8957612f6c600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612eea578181015183820152602001612ed2565b50505050905090810190601f168015612f175780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612f3457600080fd5b505afa158015612f48573d6000803e3d6000fd5b505050506040513d6020811015612f5e57600080fd5b50519063ffffffff61198f16565b848381518110612f7857fe5b602002602001018181525050613002565b60405163019af6bf60e41b8152602060048201818152835160248401528351612fe993600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612eea578181015183820152602001612ed2565b848381518110612ff557fe5b6020026020010181815250505b50600101612e4b565b600082820183811015613065576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906130a057508115155b949350505050565b6000826130b757506000610c48565b828202828482816130c457fe5b04146130655760405162461bcd60e51b81526004018080602001828103825260218152602001806138246021913960400191505060405180910390fd5b600061306583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613537565b600061306583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135d9565b613197826001600160a01b031661306c565b6131e8576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106132265780518252601f199092019160209182019101613207565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613288576040519150601f19603f3d011682016040523d82523d6000602084013e61328d565b606091505b5091509150816132e4576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611d985780806020019051602081101561330057600080fd5b5051611d985760405162461bcd60e51b815260040180806020018281038252602a815260200180613867602a913960400191505060405180910390fd5b6000805b6034548110156134295760006034828154811061335a57fe5b6000918252602082200154603480546001600160a01b039092169350613384918590811061143157fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156133d057600080fd5b505afa1580156133e4573d6000803e3d6000fd5b505050506040513d60208110156133fa57600080fd5b50519050801561341e5761341b6126d482601285900363ffffffff61198f16565b94505b505050600101613341565b5090565b6000805b603654811015613429576134756134686036838154811061344e57fe5b6000918252602090912001546001600160a01b0316613633565b839063ffffffff61300b16565b9150600101613431565b60006130658383670de0b6b3a76400006119e9565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d39908490613185565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061352584670de0b6b3a764000063ffffffff6130a816565b90506130a0818463ffffffff61310116565b600081836135c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613588578181015183820152602001613570565b50505050905090810190601f1680156135b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816135cf57fe5b0495945050505050565b6000818484111561362b5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613588578181015183820152602001613570565b505050900390565b600081815b60345481101561254e5760006136546034838154811061143157fe5b9050826001600160a01b031663aa388af66034848154811061367257fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156136c057600080fd5b505afa1580156136d4573d6000803e3d6000fd5b505050506040513d60208110156136ea57600080fd5b5051156137ad576000836001600160a01b0316635f5152266034858154811061370f57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561375d57600080fd5b505afa158015613771573d6000803e3d6000fd5b505050506040513d602081101561378757600080fd5b5051905080156137ab576137a86126d482601285900363ffffffff61198f16565b94505b505b5060010161363856fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45356e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e7472616374546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77466565206d757374206e6f742062652067726561746572207468616e207969656c645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a723158209a486e46973c6f28f9c4d92884e27d910324137adbdaefaaa0cbbf675447effe64736f6c634300050b00327bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a", + "deployedBytecode": "0x6080604052600436106101d85760003560e01c80637136a7a611610102578063af14052c11610095578063d4c3eea011610064578063d4c3eea0146105d0578063e6cc5432146105e5578063f0efb4c7146105fa578063fc0cfeee146106c9576101d8565b8063af14052c1461055e578063b888879e14610573578063c7af335214610588578063d38bfff41461059d576101d8565b80639fa1826e116100d15780639fa1826e146104ec578063a0aead4d14610501578063a403e4d514610516578063abaa991614610549576101d8565b80637136a7a61461044a5780637cbc2373146104745780638e510b52146104a45780639be918e6146104b9576101d8565b806331e19cfa1161017a578063570d8e1d11610149578063570d8e1d146103c35780635d36b190146103d85780635f515226146103ed57806367bd7ba314610420576101d8565b806331e19cfa1461035b57806349c1d54d1461037057806352d38e5d1461038557806353ca9f241461039a576101d8565b8063156e29f6116101b6578063156e29f61461028b5780631edfe3da146102cc578063207134b0146102e15780632acada4d146102f6576101d8565b806309f6442c1461021e5780630c340a2414610245578063128a8b0514610276575b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd9366000803760008036600084545af43d6000803e808015610219573d6000f35b3d6000fd5b34801561022a57600080fd5b506102336106fc565b60408051918252519081900360200190f35b34801561025157600080fd5b5061025a610702565b604080516001600160a01b039092168252519081900360200190f35b34801561028257600080fd5b5061025a610711565b34801561029757600080fd5b506102ca600480360360608110156102ae57600080fd5b506001600160a01b038135169060208101359060400135610720565b005b3480156102d857600080fd5b50610233610b33565b3480156102ed57600080fd5b50610233610b39565b34801561030257600080fd5b5061030b610b3f565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561034757818101518382015260200161032f565b505050509050019250505060405180910390f35b34801561036757600080fd5b50610233610ba1565b34801561037c57600080fd5b5061025a610ba7565b34801561039157600080fd5b50610233610bb6565b3480156103a657600080fd5b506103af610bbc565b604080519115158252519081900360200190f35b3480156103cf57600080fd5b5061025a610bcc565b3480156103e457600080fd5b506102ca610bdb565b3480156103f957600080fd5b506102336004803603602081101561041057600080fd5b50356001600160a01b0316610c3d565b34801561042c57600080fd5b5061030b6004803603602081101561044357600080fd5b5035610c4e565b34801561045657600080fd5b506102ca6004803603602081101561046d57600080fd5b5035610c59565b34801561048057600080fd5b506102ca6004803603604081101561049757600080fd5b5080359060200135610e29565b3480156104b057600080fd5b50610233610f10565b3480156104c557600080fd5b506103af600480360360208110156104dc57600080fd5b50356001600160a01b0316610f16565b3480156104f857600080fd5b50610233610f34565b34801561050d57600080fd5b50610233610f3a565b34801561052257600080fd5b5061025a6004803603602081101561053957600080fd5b50356001600160a01b0316610f40565b34801561055557600080fd5b506102ca610f5b565b34801561056a57600080fd5b506102ca611016565b34801561057f57600080fd5b5061025a6110cb565b34801561059457600080fd5b506103af6110da565b3480156105a957600080fd5b506102ca600480360360208110156105c057600080fd5b50356001600160a01b03166110fd565b3480156105dc57600080fd5b506102336111a9565b3480156105f157600080fd5b506103af6111b3565b34801561060657600080fd5b506102ca6004803603606081101561061d57600080fd5b81019060208101813564010000000081111561063857600080fd5b82018360208201111561064a57600080fd5b8035906020019184602083028401116401000000008311171561066c57600080fd5b91939092909160208101903564010000000081111561068a57600080fd5b82018360208201111561069c57600080fd5b803590602001918460208302840111640100000000831117156106be57600080fd5b9193509150356111c3565b3480156106d557600080fd5b506102ca600480360360208110156106ec57600080fd5b50356001600160a01b03166116be565b60385481565b600061070c61177f565b905090565b603e546001600160a01b031681565b603754600160a81b900460ff1615610770576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156107c8576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282556001600160a01b03851660009081526033602052604090205460ff16610832576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b60008411610887576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b6037546000906001600160a01b03166319af6bf06108a4886117a4565b6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156108f05781810151838201526020016108d8565b50505050905090810190601f16801561091d5780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b15801561093a57600080fd5b505afa15801561094e573d6000803e3d6000fd5b505050506040513d602081101561096457600080fd5b505190506305f5e10081111561097b57506305f5e1005b6000610986876118d5565b9050600061099e87601284900363ffffffff61198f16565b905060006109c86109b685600a63ffffffff61198f16565b8990600a86900a63ffffffff6119e916565b90508615610a255786811015610a25576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810183905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b548210158015610a7c5750603754600160a01b900460ff16155b15610a8957610a89611a17565b603c54604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b158015610adc57600080fd5b505af1158015610af0573d6000803e3d6000fd5b508b9250610b129150506001600160a01b03821633308c63ffffffff611d3e16565b603a548310610b2357610b23611d9e565b5050505050600182555050505050565b60395481565b60435481565b60606034805480602002602001604051908101604052809291908181526020018280548015610b9757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b79575b5050505050905090565b60365490565b6042546001600160a01b031681565b603b5481565b603754600160a01b900460ff1681565b603f546001600160a01b031681565b610be36122c1565b6001600160a01b0316336001600160a01b031614610c325760405162461bcd60e51b81526004018080602001828103825260308152602001806138916030913960400191505060405180910390fd5b610c3b336122e6565b565b6000610c4882612394565b92915050565b6060610c4882612555565b603754600160a81b900460ff1615610ca9576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610d01576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b54603c54604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610d5357600080fd5b505afa158015610d67573d6000803e3d6000fd5b505050506040513d6020811015610d7d57600080fd5b5051118015610d965750603754600160a01b900460ff16155b15610da357610da3611a17565b603c54604080516370a0823160e01b81523360048201529051610e21926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610def57600080fd5b505afa158015610e03573d6000803e3d6000fd5b505050506040513d6020811015610e1957600080fd5b505184612816565b506001905550565b603754600160a81b900460ff1615610e79576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415610ed1576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b60028255603b5484118015610ef05750603754600160a01b900460ff16155b15610efd57610efd611a17565b610f078484612816565b50600190555050565b60415481565b6001600160a01b031660009081526033602052604090205460ff1690565b603a5481565b60345490565b6040602081905260009182529020546001600160a01b031681565b603754600160a81b900460ff1615610fab576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b783398151915280546002811415611003576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611d9e565b5060019055565b603754600160a01b900460ff1615611067576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b6000805160206137b7833981519152805460028114156110bf576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b6002825561100f611a17565b6037546001600160a01b031681565b60006110e461177f565b6001600160a01b0316336001600160a01b031614905090565b6111056110da565b611156576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b61115f81612dc0565b806001600160a01b031661117161177f565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b600061070c612de4565b603754600160a81b900460ff1681565b603754600160a81b900460ff1615611213576040805162461bcd60e51b815260206004820152600e60248201526d10d85c1a5d185b081c185d5cd95960921b604482015290519081900360640190fd5b6000805160206137b78339815191528054600281141561126b576040805162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b604482015290519081900360640190fd5b600282558584146112c3576040805162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d6174636800000000000000604482015290519081900360640190fd5b60008060606112d182612e05565b905060005b8981101561150a57603360008c8c848181106112ee57fe5b602090810292909201356001600160a01b03168352508101919091526040016000205460ff1661135e576040805162461bcd60e51b8152602060048201526016602482015275105cdcd95d081a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b600089898381811061136c57fe5b90506020020135116113c5576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b60005b60345481101561150157603481815481106113df57fe5b6000918252602090912001546001600160a01b03168c8c8481811061140057fe5b905060200201356001600160a01b03166001600160a01b031614156114f957600061144b6034838154811061143157fe5b6000918252602090912001546001600160a01b03166118d5565b9050600084838151811061145b57fe5b60200260200101519050670de0b6b3a76400008111156114805750670de0b6b3a76400005b6114b86114ab836012038e8e8881811061149657fe5b9050602002013561198f90919063ffffffff16565b889063ffffffff61300b16565b96506114f46114e78284600a0a8f8f898181106114d157fe5b905060200201356119e99092919063ffffffff16565b879063ffffffff61300b16565b955050505b6001016113c8565b506001016112d6565b5085156115665785821015611566576040805162461bcd60e51b815260206004820152601e60248201527f4d696e7420616d6f756e74206c6f776572207468616e206d696e696d756d0000604482015290519081900360640190fd5b604080513381526020810184905281517f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885929181900390910190a1603b5483101580156115bd5750603754600160a01b900460ff16155b156115ca576115ca611a17565b603c54604080516340c10f1960e01b81523360048201526024810185905290516001600160a01b03909216916340c10f199160448082019260009290919082900301818387803b15801561161d57600080fd5b505af1158015611631573d6000803e3d6000fd5b506000925050505b8981101561169c5760008b8b8381811061164f57fe5b905060200201356001600160a01b0316905061169333308c8c8681811061167257fe5b90506020020135846001600160a01b0316611d3e909392919063ffffffff16565b50600101611639565b50603a5483106116ae576116ae611d9e565b5050506001825550505050505050565b6116c66110da565b611717576040805162461bcd60e51b815260206004820152601a60248201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604482015290519081900360640190fd5b6117208161306c565b61175b5760405162461bcd60e51b81526004018080602001828103825260248152602001806137d76024913960400191505060405180910390fd5b7fa2bd3d3cf188a41358c8b401076eb59066b09dec5775650c0de4c55187d17bd955565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a5490565b606080826001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561181d57600080fd5b810190808051604051939291908464010000000082111561183d57600080fd5b90830190602082018581111561185257600080fd5b825164010000000081118282018810171561186c57600080fd5b82525081516020918201929091019080838360005b83811015611899578181015183820152602001611881565b50505050905090810190601f1680156118c65780820380516001836020036101000a031916815260200191505b50604052509195945050505050565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561191157600080fd5b505afa158015611925573d6000803e3d6000fd5b505050506040513d602081101561193b57600080fd5b505160ff16905060048110801590611954575060128111155b610c485760405162461bcd60e51b81526004018080602001828103825260298152602001806137fb6029913960400191505060405180910390fd5b6000808260000b13156119ba576119b383600084900b600a0a63ffffffff6130a816565b92506119e2565b60008260000b12156119e2576119df836000848103900b600a0a63ffffffff61310116565b92505b5090919050565b6000806119fc858563ffffffff6130a816565b9050611a0e818463ffffffff61310116565b95945050505050565b603754600160a01b900460ff1615611a68576040805162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611aad57600080fd5b505afa158015611ac1573d6000803e3d6000fd5b505050506040513d6020811015611ad757600080fd5b5051905080611ae65750610c3b565b6000611af0612de4565b6042549091506001600160a01b03168015801590611b0d57508282115b15611c4f576000611b24838563ffffffff61314316565b90506000611b4f612710611b43604354856130a890919063ffffffff16565b9063ffffffff61310116565b9050808211611b8f5760405162461bcd60e51b81526004018080602001828103825260228152602001806138456022913960400191505060405180910390fd5b8015611c0357603c54604080516340c10f1960e01b81526001600160a01b03868116600483015260248201859052915191909216916340c10f1991604480830192600092919082900301818387803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b505050505b604080516001600160a01b03851681526020810184905280820183905290517f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809181900360600190a150505b603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9d57600080fd5b505afa158015611cb1573d6000803e3d6000fd5b505050506040513d6020811015611cc757600080fd5b5051925082821115611d3957603c54604080516339a7919f60e01b81526004810185905290516001600160a01b03909216916339a7919f9160248082019260009290919082900301818387803b158015611d2057600080fd5b505af1158015611d34573d6000803e3d6000fd5b505050505b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611d98908590613185565b50505050565b6000611da861333d565b905080611db55750610c3b565b6000611dbf61342d565b90506000611dd3838363ffffffff61300b16565b9050600082611dff57603954611df890670de0b6b3a76400009063ffffffff61314316565b9050611e4b565b611e1884611b43846039546130a890919063ffffffff16565b905080670de0b6b3a76400001115611e4257611df8670de0b6b3a76400008263ffffffff61314316565b50505050610c3b565b80611e595750505050610c3b565b60005b603454811015611fe857600060348281548110611e7557fe5b6000918252602080832090910154604080516370a0823160e01b815230600482015290516001600160a01b03909216945084926370a0823192602480840193829003018186803b158015611ec857600080fd5b505afa158015611edc573d6000803e3d6000fd5b505050506040513d6020811015611ef257600080fd5b5051905080611f02575050611fe0565b6000611f14828663ffffffff61347f16565b6001600160a01b03808516600090815260406020819052902054919250168015801590611f415750600082115b15611fdb5780611f616001600160a01b038616828563ffffffff61349416565b806001600160a01b03166347e7ef2486856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611fc157600080fd5b505af1158015611fd5573d6000803e3d6000fd5b50505050505b505050505b600101611e5c565b5060005b6036548110156122ba5760006036828154811061200557fe5b60009182526020808320909101546040805163125f9e3360e01b815290516001600160a01b039092169450849263125f9e3392600480840193829003018186803b15801561205257600080fd5b505afa158015612066573d6000803e3d6000fd5b505050506040513d602081101561207c57600080fd5b505190506001600160a01b038116156122b0576000826001600160a01b0316635653b4146040518163ffffffff1660e01b815260040160206040518083038186803b1580156120ca57600080fd5b505afa1580156120de573d6000803e3d6000fd5b505050506040513d60208110156120f457600080fd5b505190508061218357306001600160a01b0316630e5c011e6036868154811061211957fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561216657600080fd5b505af115801561217a573d6000803e3d6000fd5b505050506122ae565b60008290506000816001600160a01b03166370a08231603688815481106121a657fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156121f457600080fd5b505afa158015612208573d6000803e3d6000fd5b505050506040513d602081101561221e57600080fd5b505190508281106122ab57306001600160a01b0316630e5c011e6036888154811061224557fe5b6000918252602082200154604080516001600160e01b031960e086901b1681526001600160a01b039092166004830152516024808301939282900301818387803b15801561229257600080fd5b505af11580156122a6573d6000803e3d6000fd5b505050505b50505b505b5050600101611fec565b5050505050565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db5490565b6001600160a01b038116612341576040805162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f722069732061646472657373283029000000000000604482015290519081900360640190fd5b806001600160a01b031661235361177f565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a3612391816134e6565b50565b604080516370a0823160e01b8152306004820152905160009183916001600160a01b038316916370a08231916024808301926020929190829003018186803b1580156123df57600080fd5b505afa1580156123f3573d6000803e3d6000fd5b505050506040513d602081101561240957600080fd5b5051915060005b60365481101561254e5760006036828154811061242957fe5b600091825260209182902001546040805163551c457b60e11b81526001600160a01b0389811660048301529151919092169350839263aa388af69260248082019391829003018186803b15801561247f57600080fd5b505afa158015612493573d6000803e3d6000fd5b505050506040513d60208110156124a957600080fd5b50511561254557612542816001600160a01b0316635f515226876040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561250957600080fd5b505afa15801561251d573d6000803e3d6000fd5b505050506040513d602081101561253357600080fd5b5051859063ffffffff61300b16565b93505b50600101612410565b5050919050565b60606000612561610f3a565b9050606061256f6001612e05565b905060608260405190808252806020026020018201604052801561259d578160200160208202803883390190505b5090506060836040519080825280602002602001820160405280156125cc578160200160208202803883390190505b5060408051868152602080880282010190915290915060009081908680156125fe578160200160208202803883390190505b506038549097501561263d576000612627612710611b436038548c6130a890919063ffffffff16565b9050612639898263ffffffff61314316565b9850505b60005b6034548110156126ed5760006126766034838154811061265c57fe5b6000918252602090912001546001600160a01b0316612394565b9050600061268a6034848154811061143157fe5b90508187848151811061269957fe5b602002602001018181525050808684815181106126b257fe5b60209081029190910101526126e16126d483601284900363ffffffff61198f16565b869063ffffffff61300b16565b94505050600101612640565b5060005b60345481101561279e57600086828151811061270957fe5b60200260200101519050670de0b6b3a764000081101561272e5750670de0b6b3a76400005b600061278085611b43846127748a888151811061274757fe5b60200260200101516012038c898151811061275e57fe5b602002602001015161198f90919063ffffffff16565b9063ffffffff6130a816565b9050612792848263ffffffff61300b16565b935050506001016126f1565b5060006127b1898363ffffffff61350a16565b905060005b603454811015612809576127ea84611b43848985815181106127d457fe5b60200260200101516130a890919063ffffffff16565b8982815181106127f657fe5b60209081029190910101526001016127b6565b5050505050505050919050565b6000821161286b576040805162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e2030000000604482015290519081900360640190fd5b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156128b057600080fd5b505afa1580156128c4573d6000803e3d6000fd5b505050506040513d60208110156128da57600080fd5b5051905060006128e8612de4565b604154909150156129a3576000612905838363ffffffff61350a16565b9050604154670de0b6b3a7640000821161293657612931670de0b6b3a76400008363ffffffff61314316565b61294e565b61294e82670de0b6b3a764000063ffffffff61314316565b11156129a1576040805162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f720000604482015290519081900360640190fd5b505b604080513381526020810186905281517f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a6929181900390910190a160606129e985612555565b905060005b603454811015612c7f57818181518110612a0457fe5b602002602001015160001415612a1957612c77565b600060348281548110612a2857fe5b60009182526020909120015483516001600160a01b039091169150839083908110612a4f57fe5b6020026020010151816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015612aad57600080fd5b505afa158015612ac1573d6000803e3d6000fd5b505050506040513d6020811015612ad757600080fd5b505110612b1457612b0f33848481518110612aee57fe5b6020026020010151836001600160a01b03166134949092919063ffffffff16565b612c75565b60006040600060348581548110612b2757fe5b60009182526020808320909101546001600160a01b0390811684529083019390935260409091019020541690508015612c34576000819050806001600160a01b031663d9caed123360348781548110612b7c57fe5b9060005260206000200160009054906101000a90046001600160a01b0316888881518110612ba657fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015612c1657600080fd5b505af1158015612c2a573d6000803e3d6000fd5b5050505050612c73565b6040805162461bcd60e51b815260206004820152600f60248201526e2634b8bab4b234ba3c9032b93937b960891b604482015290519081900360640190fd5b505b505b6001016129ee565b508315612d2d576000805b8251811015612cd5576000612ca56034838154811061143157fe5b9050612cca612cbd8260120386858151811061275e57fe5b849063ffffffff61300b16565b925050600101612c8a565b5084811015612d2b576040805162461bcd60e51b815260206004820181905260248201527f52656465656d20616d6f756e74206c6f776572207468616e206d696e696d756d604482015290519081900360640190fd5b505b603c5460408051632770a7eb60e21b81523360048201526024810188905290516001600160a01b0390921691639dc29fac9160448082019260009290919082900301818387803b158015612d8057600080fd5b505af1158015612d94573d6000803e3d6000fd5b50505050603b5485118015612db35750603754600160a01b900460ff16155b156122ba576122ba611a17565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b600061070c612df161342d565b612df961333d565b9063ffffffff61300b16565b6060612e0f610f3a565b604051908082528060200260200182016040528015612e38578160200160208202803883390190505b506037549091506001600160a01b031660005b60345481101561254e576060612e8160348381548110612e6757fe5b6000918252602090912001546001600160a01b03166117a4565b90508415612f8957612f6c600a846001600160a01b0316637bf0c215846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612eea578181015183820152602001612ed2565b50505050905090810190601f168015612f175780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b158015612f3457600080fd5b505afa158015612f48573d6000803e3d6000fd5b505050506040513d6020811015612f5e57600080fd5b50519063ffffffff61198f16565b848381518110612f7857fe5b602002602001018181525050613002565b60405163019af6bf60e41b8152602060048201818152835160248401528351612fe993600a936001600160a01b038916936319af6bf093889391928392604401919085019080838360008315612eea578181015183820152602001612ed2565b848381518110612ff557fe5b6020026020010181815250505b50600101612e4b565b600082820183811015613065576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906130a057508115155b949350505050565b6000826130b757506000610c48565b828202828482816130c457fe5b04146130655760405162461bcd60e51b81526004018080602001828103825260218152602001806138246021913960400191505060405180910390fd5b600061306583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613537565b600061306583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135d9565b613197826001600160a01b031661306c565b6131e8576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106132265780518252601f199092019160209182019101613207565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613288576040519150601f19603f3d011682016040523d82523d6000602084013e61328d565b606091505b5091509150816132e4576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611d985780806020019051602081101561330057600080fd5b5051611d985760405162461bcd60e51b815260040180806020018281038252602a815260200180613867602a913960400191505060405180910390fd5b6000805b6034548110156134295760006034828154811061335a57fe5b6000918252602082200154603480546001600160a01b039092169350613384918590811061143157fe5b604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156133d057600080fd5b505afa1580156133e4573d6000803e3d6000fd5b505050506040513d60208110156133fa57600080fd5b50519050801561341e5761341b6126d482601285900363ffffffff61198f16565b94505b505050600101613341565b5090565b6000805b603654811015613429576134756134686036838154811061344e57fe5b6000918252602090912001546001600160a01b0316613633565b839063ffffffff61300b16565b9150600101613431565b60006130658383670de0b6b3a76400006119e9565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611d39908490613185565b7f7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a55565b60008061352584670de0b6b3a764000063ffffffff6130a816565b90506130a0818463ffffffff61310116565b600081836135c35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613588578181015183820152602001613570565b50505050905090810190601f1680156135b55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816135cf57fe5b0495945050505050565b6000818484111561362b5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613588578181015183820152602001613570565b505050900390565b600081815b60345481101561254e5760006136546034838154811061143157fe5b9050826001600160a01b031663aa388af66034848154811061367257fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b1580156136c057600080fd5b505afa1580156136d4573d6000803e3d6000fd5b505050506040513d60208110156136ea57600080fd5b5051156137ad576000836001600160a01b0316635f5152266034858154811061370f57fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561375d57600080fd5b505afa158015613771573d6000803e3d6000fd5b505050506040513d602081101561378757600080fd5b5051905080156137ab576137a86126d482601285900363ffffffff61198f16565b94505b505b5060010161363856fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45356e657720696d706c656d656e746174696f6e206973206e6f74206120636f6e7472616374546f6b656e206d75737420686176652073756666696369656e7420646563696d616c20706c61636573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77466565206d757374206e6f742062652067726561746572207468616e207969656c645361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f6d706c6574652074686520636c61696da265627a7a723158209a486e46973c6f28f9c4d92884e27d910324137adbdaefaaa0cbbf675447effe64736f6c634300050b0032", "devdoc": { "methods": { "allocate()": { @@ -823,8 +898,7 @@ } }, "rebase()": { - "details": "Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD.", - "return": "uint256 New total supply of OUSD" + "details": "Calculate the total value of assets held by the Vault and all strategies and update the supply of OUSD." }, "redeem(uint256,uint256)": { "details": "Withdraw a supported asset and burn OUSD.", @@ -841,7 +915,7 @@ "setAdminImpl(address)": { "details": "set the implementation for the admin, this needs to be in a base class else we cannot set it", "params": { - "newImpl": "address pf the implementation" + "newImpl": "address of the implementation" } }, "totalValue()": { diff --git a/contracts/storageLayout/mainnet/VaultCore.json b/contracts/storageLayout/mainnet/VaultCore.json index 7801923332..630024aacb 100644 --- a/contracts/storageLayout/mainnet/VaultCore.json +++ b/contracts/storageLayout/mainnet/VaultCore.json @@ -21,114 +21,126 @@ { "contract": "VaultStorage", "label": "assets", - "type": "t_mapping(t_address,t_struct(Asset)16756_storage)", - "src": "contracts/vault/VaultStorage.sol:52" + "type": "t_mapping(t_address,t_struct(Asset)16977_storage)", + "src": "contracts/vault/VaultStorage.sol:55" }, { "contract": "VaultStorage", "label": "allAssets", "type": "t_array(t_address)dyn_storage", - "src": "contracts/vault/VaultStorage.sol:53" + "src": "contracts/vault/VaultStorage.sol:56" }, { "contract": "VaultStorage", "label": "strategies", - "type": "t_mapping(t_address,t_struct(Strategy)16768_storage)", - "src": "contracts/vault/VaultStorage.sol:60" + "type": "t_mapping(t_address,t_struct(Strategy)16989_storage)", + "src": "contracts/vault/VaultStorage.sol:63" }, { "contract": "VaultStorage", "label": "allStrategies", "type": "t_array(t_address)dyn_storage", - "src": "contracts/vault/VaultStorage.sol:61" + "src": "contracts/vault/VaultStorage.sol:64" }, { "contract": "VaultStorage", "label": "priceProvider", "type": "t_address", - "src": "contracts/vault/VaultStorage.sol:64" + "src": "contracts/vault/VaultStorage.sol:67" }, { "contract": "VaultStorage", "label": "rebasePaused", "type": "t_bool", - "src": "contracts/vault/VaultStorage.sol:66" + "src": "contracts/vault/VaultStorage.sol:69" }, { "contract": "VaultStorage", "label": "capitalPaused", "type": "t_bool", - "src": "contracts/vault/VaultStorage.sol:67" + "src": "contracts/vault/VaultStorage.sol:70" }, { "contract": "VaultStorage", "label": "redeemFeeBps", "type": "t_uint256", - "src": "contracts/vault/VaultStorage.sol:69" + "src": "contracts/vault/VaultStorage.sol:72" }, { "contract": "VaultStorage", "label": "vaultBuffer", "type": "t_uint256", - "src": "contracts/vault/VaultStorage.sol:71" + "src": "contracts/vault/VaultStorage.sol:74" }, { "contract": "VaultStorage", "label": "autoAllocateThreshold", "type": "t_uint256", - "src": "contracts/vault/VaultStorage.sol:73" + "src": "contracts/vault/VaultStorage.sol:76" }, { "contract": "VaultStorage", "label": "rebaseThreshold", "type": "t_uint256", - "src": "contracts/vault/VaultStorage.sol:75" + "src": "contracts/vault/VaultStorage.sol:78" }, { "contract": "VaultStorage", "label": "oUSD", - "type": "t_contract(OUSD)13287", - "src": "contracts/vault/VaultStorage.sol:77" + "type": "t_contract(OUSD)13422", + "src": "contracts/vault/VaultStorage.sol:80" }, { "contract": "VaultStorage", "label": "_deprecated_rebaseHooksAddr", "type": "t_address", - "src": "contracts/vault/VaultStorage.sol:83" + "src": "contracts/vault/VaultStorage.sol:86" }, { "contract": "VaultStorage", "label": "uniswapAddr", "type": "t_address", - "src": "contracts/vault/VaultStorage.sol:86" + "src": "contracts/vault/VaultStorage.sol:89" }, { "contract": "VaultStorage", "label": "strategistAddr", "type": "t_address", - "src": "contracts/vault/VaultStorage.sol:89" + "src": "contracts/vault/VaultStorage.sol:92" }, { "contract": "VaultStorage", "label": "assetDefaultStrategies", "type": "t_mapping(t_address,t_address)", - "src": "contracts/vault/VaultStorage.sol:93" + "src": "contracts/vault/VaultStorage.sol:96" }, { "contract": "VaultStorage", "label": "maxSupplyDiff", "type": "t_uint256", - "src": "contracts/vault/VaultStorage.sol:95" + "src": "contracts/vault/VaultStorage.sol:98" + }, + { + "contract": "VaultStorage", + "label": "trusteeAddress", + "type": "t_address", + "src": "contracts/vault/VaultStorage.sol:101" + }, + { + "contract": "VaultStorage", + "label": "trusteeFeeBps", + "type": "t_uint256", + "src": "contracts/vault/VaultStorage.sol:104" } ], "types": { - "t_mapping(t_address,t_struct(Asset)16756_storage)": { + "t_mapping(t_address,t_struct(Asset)16977_storage)": { "label": "mapping(address => struct VaultStorage.Asset)" }, "t_address": { "label": "address" }, - "t_struct(Asset)16756_storage": { + "t_struct(Asset)16977_storage": { "label": "struct VaultStorage.Asset", "members": [ { @@ -143,10 +155,10 @@ "t_array(t_address)dyn_storage": { "label": "address[]" }, - "t_mapping(t_address,t_struct(Strategy)16768_storage)": { + "t_mapping(t_address,t_struct(Strategy)16989_storage)": { "label": "mapping(address => struct VaultStorage.Strategy)" }, - "t_struct(Strategy)16768_storage": { + "t_struct(Strategy)16989_storage": { "label": "struct VaultStorage.Strategy", "members": [ { @@ -162,7 +174,7 @@ "t_uint256": { "label": "uint256" }, - "t_contract(OUSD)13287": { + "t_contract(OUSD)13422": { "label": "contract OUSD" }, "t_mapping(t_address,t_address)": { diff --git a/dapp/network.mainnet.json b/dapp/network.mainnet.json index 3970e8f340..b574aa9759 100644 --- a/dapp/network.mainnet.json +++ b/dapp/network.mainnet.json @@ -10582,7 +10582,7 @@ ] }, "VaultCore": { - "address": "0xE54f14FC3fBc5915D070DE4758bcF591541BD1c3", + "address": "0x3e803eEA623eE4793f0f49790A813811da5249f4", "abi": [ { "constant": true, @@ -10669,6 +10669,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeFeeBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -10699,6 +10714,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -10930,13 +10960,7 @@ "constant": false, "inputs": [], "name": "rebase", - "outputs": [ - { - "internalType": "uint256", - "name": "newTotalSupply", - "type": "uint256" - } - ], + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -11285,6 +11309,57 @@ "name": "MaxSupplyDiffChanged", "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" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_basis", + "type": "uint256" + } + ], + "name": "TrusteeFeeBpsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "TrusteeAddressChanged", + "type": "event" + }, { "anonymous": false, "inputs": [ diff --git a/dapp/network.rinkeby.json b/dapp/network.rinkeby.json index 8cae829324..009799420b 100644 --- a/dapp/network.rinkeby.json +++ b/dapp/network.rinkeby.json @@ -19564,7 +19564,7 @@ ] }, "VaultCore": { - "address": "0x1376fE696858E0163a886eBcFCf3f5eB24BC9ac4", + "address": "0x1D6B56e17D08e83dc2198A61Cb5BC9744cF8D9fE", "abi": [ { "constant": true, @@ -19651,6 +19651,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeFeeBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -19681,6 +19696,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "trusteeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -19912,13 +19942,7 @@ "constant": false, "inputs": [], "name": "rebase", - "outputs": [ - { - "internalType": "uint256", - "name": "newTotalSupply", - "type": "uint256" - } - ], + "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" @@ -20267,6 +20291,57 @@ "name": "MaxSupplyDiffChanged", "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" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_basis", + "type": "uint256" + } + ], + "name": "TrusteeFeeBpsChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "TrusteeAddressChanged", + "type": "event" + }, { "anonymous": false, "inputs": [