{"file_path":"contracts/vault/OUSDVault.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport { VaultAdmin } from \"./VaultAdmin.sol\";\n\n/**\n * @title OUSD VaultAdmin Contract\n * @author Origin Protocol Inc\n */\ncontract OUSDVault is VaultAdmin {\n    constructor(address _usdc) VaultAdmin(_usdc) {}\n}\n","deployed_bytecode":"0x608060405234801561001057600080fd5b50600436106104075760003560e01c8063663e64ce11610220578063ae69f3cb11610130578063c7af3352116100b8578063e6cc543211610087578063e6cc5432146109e5578063ea33b8e4146109f9578063f3f18c3714610a01578063f844443614610a14578063fac5bb9b14610a2757600080fd5b8063c7af3352146109ba578063c9919112146109c2578063d38bfff4146109ca578063d4c3eea0146109dd57600080fd5b8063b9b17f9f116100ff578063b9b17f9f14610975578063bb7a632e1461097d578063c3b2886414610997578063c4d66de81461099f578063c5f00841146109b257600080fd5b8063ae69f3cb14610934578063af14052c14610947578063b2c9336d1461094f578063b4925a201461096257600080fd5b806395b166bc116101b35780639fa1826e116101825780639fa1826e146108f6578063a0712d68146108ff578063a0aead4d14610912578063ab80dafb14610919578063abaa99161461092c57600080fd5b806395b166bc146108685780639be918e61461087b5780639e428552146108bb5780639ee679e8146108ce57600080fd5b80638e510b52116101ef5780638e510b521461079c5780638ec489a2146107a5578063937b2581146107b857806394828ffd1461086057600080fd5b8063663e64ce14610750578063773540b31461076357806378f353a114610776578063840c4c7a1461078957600080fd5b806339ebf8231161031b578063527e83a8116102ae5780635802a1721161027d5780635802a172146106fe578063597c89101461070f5780635d36b190146107225780635f5152261461072a5780636217f3ea1461073d57600080fd5b8063527e83a8146106aa57806353ca9f24146106c4578063570d8e1d146106d857806357bee944146106eb57600080fd5b806345e4213b116102ea57806345e4213b1461063b57806348e30f541461064457806349c1d54d146106655780634d5f46291461067857600080fd5b806339ebf823146105a95780633b8ae397146105ed5780633dbc911f146106005780634530820a1461060857600080fd5b80631a32aad61161039e5780632acada4d1161036d5780632acada4d146104f35780632da845a81461050857806331e19cfa1461051b578063362bd1a31461052357806338d52e0f1461058257600080fd5b80631a32aad6146104ad5780631cfbe7bc146104c05780631edfe3da146104d3578063207134b0146104ea57600080fd5b80631072cbea116103da5780631072cbea14610461578063156e29f614610474578063175188e8146104875780631816dd4a1461049a57600080fd5b80630493a0fa1461040c57806309f49bf5146104215780630acbda75146104295780630c340a241461043c575b600080fd5b61041f61041a366004614b54565b610a3a565b005b61041f610af0565b61041f610437366004614b54565b610b60565b610444610c0b565b6040516001600160a01b0390911681526020015b60405180910390f35b61041f61046f366004614b89565b610c28565b61041f610482366004614bb3565b610ce6565b61041f610495366004614be6565b610d59565b61041f6104a8366004614be6565b6110f7565b603c54610444906001600160a01b031681565b61041f6104ce366004614b54565b6111fe565b6104dc60395481565b604051908152602001610458565b6104dc60435481565b6104fb6112c0565b6040516104589190614c01565b61041f610516366004614be6565b611337565b6036546104dc565b604b54604c5461054f916001600160801b0380821692600160801b928390048216928183169291041684565b604080516001600160801b0395861681529385166020850152918416918301919091529091166060820152608001610458565b6104447f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b6105d66105b7366004614be6565b6035602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610458565b61041f6105fb366004614be6565b6113a9565b61041f6115bc565b61062b610616366004614be6565b60496020526000908152604090205460ff1681565b6040519015158152602001610458565b6104dc604e5481565b610657610652366004614c91565b611632565b604051610458929190614cd2565b604254610444906001600160a01b031681565b604f5461069290600160c01b90046001600160401b031681565b6040516001600160401b039091168152602001610458565b604f5461069290600160801b90046001600160401b031681565b60375461062b90600160a01b900460ff1681565b603f54610444906001600160a01b031681565b61041f6106f9366004614be6565b6117a8565b603c546001600160a01b0316610444565b61041f61071d366004614be6565b61195b565b61041f61199f565b6104dc610738366004614be6565b611a45565b61041f61074b366004614b54565b611a56565b61041f61075e366004614b54565b611bda565b61041f610771366004614be6565b611c33565b604f54610692906001600160401b031681565b61041f610797366004614d1f565b611ca5565b6104dc60415481565b61041f6107b3366004614b54565b611d2c565b6108196107c6366004614b54565b604d60205260009081526040902080546001909101546001600160a01b03821691600160a01b810460ff1691600160a81b90910464ffffffffff16906001600160801b0380821691600160801b90041685565b604080516001600160a01b039096168652931515602086015264ffffffffff909216928401929092526001600160801b03918216606084015216608082015260a001610458565b61041f611de1565b61041f610876366004614be6565b611e51565b61062b610889366004614be6565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0390811691161490565b61041f6108c9366004614be6565b611f18565b6108e16108dc366004614b54565b611f8a565b60408051928352602083019190915201610458565b6104dc603a5481565b61041f61090d366004614b54565b6122ca565b60016104dc565b61041f610927366004614b54565b61233b565b61041f61248a565b61041f610942366004614d1f565b612502565b61041f61257e565b61041f61095d366004614b54565b612639565b61041f610970366004614b54565b612692565b61041f6127b0565b604f5461069290600160401b90046001600160401b031681565b6104fb6127b8565b61041f6109ad366004614be6565b61281a565b61041f6129c5565b61062b612a3b565b61041f612a6c565b61041f6109d8366004614be6565b612aac565b6104dc612b50565b60375461062b90600160a81b900460ff1681565b6104dc612b5a565b605154610444906001600160a01b031681565b6104dc610a22366004614b54565b612be9565b605054610444906001600160a01b031681565b603f546001600160a01b0316331480610a565750610a56612a3b565b610a7b5760405162461bcd60e51b8152600401610a7290614da3565b60405180910390fd5b610a83612cda565b50610a8d81613074565b604f80546001600160401b0392909216600160401b0267ffffffffffffffff60401b199092169190911790556040518181527f406e15fbca1d8ded2dbb06765fea3a54f18395c54125a4c9916dd00ea14ee15e906020015b60405180910390a150565b603f546001600160a01b0316331480610b0c5750610b0c612a3b565b610b285760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a01b191690556040517fbc044409505c95b6b851433df96e1beae715c909d8e7c1d6d7ab783300d4e3b990600090a1565b610b68612a3b565b610b845760405162461bcd60e51b8152600401610a7290614deb565b611388811115610bd65760405162461bcd60e51b815260206004820152601760248201527f62617369732063616e6e6f7420657863656564203530250000000000000000006044820152606401610a72565b60438190556040518181527f56287a45051933ea374811b3d5d165033047be5572cac676f7c28b8be4f746c790602001610ae5565b6000610c236000805160206151718339815191525490565b905090565b610c30612a3b565b610c4c5760405162461bcd60e51b8152600401610a7290614deb565b816001600160a01b03167f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031603610cc65760405162461bcd60e51b815260206004820152601660248201527513db9b1e481d5b9cdd5c1c1bdc9d195908185cdcd95d60521b6044820152606401610a72565b610ce2610cd1610c0b565b6001600160a01b03841690836130e0565b5050565b603754600160a81b900460ff1615610d105760405162461bcd60e51b8152600401610a7290614e22565b60008051602061515183398151915280546001198101610d425760405162461bcd60e51b8152600401610a7290614e4a565b60028255610d4f84613136565b5060019055505050565b610d61612a3b565b610d7d5760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526035602052604090205460ff16610db55760405162461bcd60e51b8152600401610a7290614e72565b6050546001600160a01b03808316911603610e125760405162461bcd60e51b815260206004820152601d60248201527f53747261746567792069732064656661756c7420666f722061737365740000006044820152606401610a72565b6036548060005b82811015610e6857836001600160a01b031660368281548110610e3e57610e3e614ea1565b6000918252602090912001546001600160a01b031603610e6057809150610e68565b600101610e19565b50818110156110f2576036610e7e600184614ecd565b81548110610e8e57610e8e614ea1565b600091825260209091200154603680546001600160a01b039092169183908110610eba57610eba614ea1565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506036805480610ef957610ef9614ee0565b6001900381819060005260206000200160006101000a8154906001600160a01b03021916905590556000839050806001600160a01b031663853828b66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610f6157600080fd5b505af1158015610f75573d6000803e3d6000fd5b505050506001600160a01b0384166000908152603560209081526040808320805460ff199081169091556049909252822080549091169055610fe26509184e72a00060ff7f00000000000000000000000000000000000000000000000000000000000000061660126132a7565b604051632fa8a91360e11b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811660048301529192508291841690635f51522690602401602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110719190614ef6565b106110b35760405162461bcd60e51b81526020600482015260126024820152715374726174656779206861732066756e647360701b6044820152606401610a72565b6040516001600160a01b03861681527f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea49060200160405180910390a150505b505050565b6110ff612a3b565b61111b5760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526035602052604090205460ff166111535760405162461bcd60e51b8152600401610a7290614e72565b6001600160a01b03811660009081526049602052604090205460ff16156111b25760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481dda1a5d195b1a5cdd1959606a1b6044820152606401610a72565b6001600160a01b038116600081815260496020526040808220805460ff19166001179055517f47c8c96a5942f094264111c5fe7f6a4fe86efe63254a6fa7afa5fc84f07d58e89190a250565b611206612a3b565b6112225760405162461bcd60e51b8152600401610a7290614deb565b80158061123f5750610258811015801561123f57506213c6808111155b61128b5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420636c61696d2064656c617920706572696f640000000000006044820152606401610a72565b604e8190556040518181527fc59f5e32049abab44ddea11021f5abb89422a2f550837afcf25df9fc8d0db6b090602001610ae5565b60408051600180825281830190925260609160009190602080830190803683370190505090507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160008151811061131a5761131a614ea1565b6001600160a01b0390921660209283029190910190910152919050565b61133f612a3b565b61135b5760405162461bcd60e51b8152600401610a7290614deb565b604280546001600160a01b0319166001600160a01b0383169081179091556040519081527f1e4af5ac389e8cde1bdaa6830881b6c987c62a45cfb3b33d27d805cde3b5775090602001610ae5565b6113b1612a3b565b6113cd5760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526035602052604090205460ff16156114365760405162461bcd60e51b815260206004820152601960248201527f537472617465677920616c726561647920617070726f766564000000000000006044820152606401610a72565b60405163551c457b60e11b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488116600483015282169063aa388af690602401602060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190614f25565b61150c5760405162461bcd60e51b815260206004820152601f60248201527f4173736574206e6f7420737570706f72746564206279205374726174656779006044820152606401610a72565b6040805180820182526001808252600060208084018281526001600160a01b038716808452603583528684209551865460ff19169015151786559051948401949094556036805493840181559091527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b890910180546001600160a01b0319168317905591519081527f960dd94cbb79169f09a4e445d58b895df2d9bffa5b31055d0932d801724a20d19101610ae5565b603f546001600160a01b03163314806115d857506115d8612a3b565b6115f45760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a81b1916600160a81b1790556040517f71f0e5b62f846a22e0b4d159e516e62fa9c2b8eb570be15f83e67d98a2ee51e090600090a1565b603754606090600090600160a81b900460ff16156116625760405162461bcd60e51b8152600401610a7290614e22565b600080516020615151833981519152805460011981016116945760405162461bcd60e51b8152600401610a7290614e4a565b600282556116a061330b565b50846001600160401b038111156116b9576116b9614f0f565b6040519080825280602002602001820160405280156116e2578160200160208202803683370190505b50935060005b8581101561175e5761171187878381811061170557611705614ea1565b905060200201356134e7565b85828151811061172357611723614ea1565b60200260200101818152505084818151811061174157611741614ea1565b6020026020010151846117549190614f47565b93506001016116e8565b506117936001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481633856130e0565b61179b613848565b6001825550509250929050565b603f546001600160a01b03163314806117c457506117c4612a3b565b6117e05760405162461bcd60e51b8152600401610a7290614da3565b6040516001600160a01b03821681527f45a9e715f8779ebeab88d3e8d081fb8b484b7730857e7c4478a95a5b1d8f79489060200160405180910390a16001600160a01b03811615611939576001600160a01b03811660009081526035602052604090205460ff166118635760405162461bcd60e51b8152600401610a7290614e72565b60405163551c457b60e11b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488116600483015282169063aa388af690602401602060405180830381865afa1580156118c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ed9190614f25565b6119395760405162461bcd60e51b815260206004820152601f60248201527f4173736574206e6f7420737570706f72746564206279205374726174656779006044820152606401610a72565b605080546001600160a01b0319166001600160a01b0392909216919091179055565b603f546001600160a01b03163314806119775750611977612a3b565b6119935760405162461bcd60e51b8152600401610a7290614da3565b61199c816139bb565b50565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614611a3a5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b6064820152608401610a72565b611a4333613a83565b565b6000611a5082613ae2565b92915050565b603754600160a81b900460ff1615611a805760405162461bcd60e51b8152600401610a7290614e22565b3360009081526035602052604090205460ff161515600114611adb5760405162461bcd60e51b8152602060048201526014602482015273556e737570706f7274656420737472617465677960601b6044820152606401610a72565b3360009081526049602052604090205460ff161515600114611b3a5760405162461bcd60e51b81526020600482015260186024820152774e6f742077686974656c697374656420737472617465677960401b6044820152606401610a72565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63382604051611b6b929190614f5a565b60405180910390a1603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90611ba59033908590600401614f5a565b600060405180830381600087803b158015611bbf57600080fd5b505af1158015611bd3573d6000803e3d6000fd5b5050505050565b611be2612a3b565b611bfe5760405162461bcd60e51b8152600401610a7290614deb565b60418190556040518181527f95201f9c21f26877223b1ff4073936a6484c35495649e60e55730497aeb60d9390602001610ae5565b611c3b612a3b565b611c575760405162461bcd60e51b8152600401610a7290614deb565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f869e0abd13cc3a975de7b93be3df1cb2255c802b1cead85963cc79d99f131bee90602001610ae5565b603f546001600160a01b0316331480611cc15750611cc1612a3b565b611cdd5760405162461bcd60e51b8152600401610a7290614da3565b60008051602061515183398151915280546001198101611d0f5760405162461bcd60e51b8152600401610a7290614e4a565b60028255611d208787878787613d44565b50600190555050505050565b603f546001600160a01b0316331480611d485750611d48612a3b565b611d645760405162461bcd60e51b8152600401610a7290614da3565b670de0b6b3a7640000811115611dac5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c69642076616c756560981b6044820152606401610a72565b60398190556040518181527f41ecb23a0e7865b25f38c268b7c3012220d822929e9edff07326e89d5bb822b590602001610ae5565b603f546001600160a01b0316331480611dfd5750611dfd612a3b565b611e195760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a81b191690556040517f891ebab18da80ebeeea06b1b1cede098329c4c008906a98370c2ac7a80b571cb90600090a1565b611e59612a3b565b611e755760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526049602052604090205460ff16611ecf5760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610a72565b6001600160a01b038116600081815260496020526040808220805460ff19169055517f0ec40967a61509853550658e51d0e4297f7cba244fe4adc8ba18b5631ac20e2f9190a250565b611f20612a3b565b611f3c5760405162461bcd60e51b8152600401610a7290614deb565b605180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3b3f5f64ab192e4b5fefde1f51ce9733bbdcf831951543b325aebd49cc27ec490602001610ae5565b6037546000908190600160a81b900460ff1615611fb95760405162461bcd60e51b8152600401610a7290614e22565b60008051602061515183398151915280546001198101611feb5760405162461bcd60e51b8152600401610a7290614e4a565b600282556000851161203f5760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606401610a72565b6000604e54116120915760405162461bcd60e51b815260206004820152601d60248201527f4173796e63207769746864726177616c73206e6f7420656e61626c65640000006044820152606401610a72565b604c54600160801b90046001600160801b031693506120d5857f000000000000000000000000000000000000000000000000000000000000000660ff1660126132a7565b604b546120eb91906001600160801b0316614f47565b92506121006120fb856001614f47565b613f83565b604c80546001600160801b03928316600160801b02921691909117905561212683613f83565b604b80546001600160801b0319166001600160801b03929092169190911790556040805160a081018252338152600060208201524264ffffffffff16918101919091526060810161217687613f83565b6001600160801b0316815260200161218d85613f83565b6001600160801b039081169091526000868152604d602090815260409182902084518154928601518685015164ffffffffff16600160a81b0264ffffffffff60a81b19911515600160a01b026001600160a81b03199095166001600160a01b0393841617949094171692909217815560608501516080909501518416600160801b029490931693909317600190920191909155603c549051632770a7eb60e21b8152911690639dc29fac906122489033908990600401614f5a565b600060405180830381600087803b15801561226257600080fd5b505af1158015612276573d6000803e3d6000fd5b50505050612282613848565b6040805186815260208101859052859133917f38e3d972947cfef94205163d483d6287ef27eb312e20cb8e0b13a49989db232e910160405180910390a3600182555050915091565b603754600160a81b900460ff16156122f45760405162461bcd60e51b8152600401610a7290614e22565b600080516020615151833981519152805460011981016123265760405162461bcd60e51b8152600401610a7290614e4a565b6002825561233383613136565b506001905550565b603754600160a81b900460ff16156123655760405162461bcd60e51b8152600401610a7290614e22565b3360009081526035602052604090205460ff1615156001146123c05760405162461bcd60e51b8152602060048201526014602482015273556e737570706f7274656420737472617465677960601b6044820152606401610a72565b3360009081526049602052604090205460ff16151560011461241f5760405162461bcd60e51b81526020600482015260186024820152774e6f742077686974656c697374656420737472617465677960401b6044820152606401610a72565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853382604051612450929190614f5a565b60405180910390a1603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990611ba59033908590600401614f5a565b603754600160a81b900460ff16156124b45760405162461bcd60e51b8152600401610a7290614e22565b600080516020615151833981519152805460011981016124e65760405162461bcd60e51b8152600401610a7290614e4a565b600282556124f261330b565b506124fb613fec565b5060019055565b603f546001600160a01b031633148061251e575061251e612a3b565b61253a5760405162461bcd60e51b8152600401610a7290614da3565b6000805160206151518339815191528054600119810161256c5760405162461bcd60e51b8152600401610a7290614e4a565b60028255611d20308888888888614215565b600080516020615151833981519152805460011981016125b05760405162461bcd60e51b8152600401610a7290614e4a565b600282556051546001600160a01b03163314806125d75750603f546001600160a01b031633145b806125e557506125e5612a3b565b6126295760405162461bcd60e51b815260206004820152601560248201527410d85b1b195c881b9bdd08185d5d1a1bdc9a5e9959605a1b6044820152606401610a72565b612631612cda565b505060019055565b612641612a3b565b61265d5760405162461bcd60e51b8152600401610a7290614deb565b603a8190556040518181527f2ec5fb5a3d2703edc461252d92ccd2799c3c74f01d97212b20388207fa17ae4590602001610ae5565b603f546001600160a01b03163314806126ae57506126ae612a3b565b6126ca5760405162461bcd60e51b8152600401610a7290614da3565b6126d2612cda565b5060006301e133806126e5606484614f73565b6126ef9190614f73565b90506127056201518066b1a2bc2ec50000614f73565b8111156127445760405162461bcd60e51b815260206004820152600d60248201526c0a4c2e8ca40e8dede40d0d2ced609b1b6044820152606401610a72565b61274d81613074565b604f80546001600160401b0392909216600160801b0267ffffffffffffffff60801b199092169190911790556040518181527fef46f143af5fead0010484fe7d6ec2e2972420faa76157f5a6075aa72e614cb59060200160405180910390a15050565b61199c61330b565b6060603680548060200260200160405190810160405280929190818152602001828054801561281057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116127f2575b5050505050905090565b612822612a3b565b61283e5760405162461bcd60e51b8152600401610a7290614deb565b600054610100900460ff1680612857575060005460ff16155b6128ba5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a72565b600054610100900460ff161580156128dc576000805461ffff19166101011790555b6001600160a01b03821661292b5760405162461bcd60e51b81526020600482015260166024820152756f546f6b656e2061646472657373206973207a65726f60501b6044820152606401610a72565b603c80546001600160a01b0384166001600160a01b03199091161790556037805461ffff60a01b1916600160a81b1790556000603981905569054b40b1f852bda00000603a55604080519182526020820190819052905161298e91603691614ae3565b50604f805467ffffffffffffffff60401b19166a093a8000000000000000001790558015610ce2576000805461ff00191690555050565b603f546001600160a01b03163314806129e157506129e1612a3b565b6129fd5760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a01b1916600160a01b1790556040517f8cff26a5985614b3d30629cc4ab83824bf115aec971b718d8f2f99562032e97290600090a1565b6000612a536000805160206151718339815191525490565b6001600160a01b0316336001600160a01b031614905090565b603f546001600160a01b0316331480612a885750612a88612a3b565b612aa45760405162461bcd60e51b8152600401610a7290614da3565b611a436143a6565b612ab4612a3b565b612ad05760405162461bcd60e51b8152600401610a7290614deb565b612af8817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b0316612b186000805160206151718339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b6000610c2361443b565b6000612be3603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd69190614ef6565b612bde61443b565b61448f565b50919050565b603754600090600160a81b900460ff1615612c165760405162461bcd60e51b8152600401610a7290614e22565b60008051602061515183398151915280546001198101612c485760405162461bcd60e51b8152600401610a7290614e4a565b60028255604b546000858152604d60205260409020600101546001600160801b03600160801b92839004811692909104161115612c8957612c8761330b565b505b612c92846134e7565b9250612cc86001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481633856130e0565b612cd0613848565b5060019055919050565b603754600090600160a01b900460ff1615612d295760405162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b6044820152606401610a72565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015612d73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d979190614ef6565b90506000612da361443b565b905081600003612db65791506130719050565b600080612dc3848461448f565b90925090506000612dd48386614f47565b90508481111580612de457508381115b15612df3575091949350505050565b612e04826001600160401b03614662565b604f805477ffffffffffffffffffffffffffffffff000000000000000016600160c01b6001600160401b039384160267ffffffffffffffff19161742929092169190911790556042546001600160a01b031660008115612f405761271060435486612e6f9190614f95565b612e799190614f73565b90508015612f4057848110612edb5760405162461bcd60e51b815260206004820152602260248201527f466565206d757374206e6f742062652067726561746572207468616e207969656044820152611b1960f21b6064820152608401610a72565b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990612f0d9085908590600401614f5a565b600060405180830381600087803b158015612f2757600080fd5b505af1158015612f3b573d6000803e3d6000fd5b505050505b604080516001600160a01b0384168152602081018790529081018290527f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809060600160405180910390a1603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130019190614ef6565b83111561306757603c546040516339a7919f60e01b8152600481018590526001600160a01b03909116906339a7919f90602401600060405180830381600087803b15801561304e57600080fd5b505af1158015613062573d6000803e3d6000fd5b505050505b5093955050505050505b90565b60006001600160401b038211156130dc5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608401610a72565b5090565b6110f28363a9059cbb60e01b84846040516024016130ff929190614f5a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614678565b600081116131865760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606401610a72565b60006131b782601260ff7f0000000000000000000000000000000000000000000000000000000000000006166132a7565b90507f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688533826040516131ea929190614f5a565b60405180910390a1603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906132249033908590600401614f5a565b600060405180830381600087803b15801561323e57600080fd5b505af1158015613252573d6000803e3d6000fd5b5061328d9250506001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816905033308561474a565b61329561330b565b50603a548110610ce257610ce2613fec565b6000818311156132d7576132d06132be8385614ecd565b6132c990600a615093565b8590614788565b9350613301565b81831015613301576132fe6132ec8484614ecd565b6132f790600a615093565b8590614794565b93505b50825b9392505050565b60408051608081018252604b546001600160801b03808216808452600160801b92839004821660208501819052604c548084169686019690965292909404166060830152600092839161335d9161509f565b6001600160801b03169050806000036133795760009250505090565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a0823190602401602060405180830381865afa1580156133e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134049190614ef6565b905060008360400151846020015161341c919061509f565b6001600160801b0316905080821161343957600094505050505090565b60006134458284614ecd565b90508084106134545780613456565b835b955060008686602001516001600160801b03166134739190614f47565b905061347e81613f83565b604b80546001600160801b03928316600160801b0292169190911790556040517fee79a0c43d3993055690b54e074b5153e8bae8d1a872b656dedb64aa8f463333906134d69083908a90918252602082015260400190565b60405180910390a150505050505090565b600080604e541161353a5760405162461bcd60e51b815260206004820152601d60248201527f4173796e63207769746864726177616c73206e6f7420656e61626c65640000006044820152606401610a72565b6000828152604d6020908152604091829020825160a08101845281546001600160a01b038116825260ff600160a01b82041615158285015264ffffffffff600160a81b90910481168286019081526001909301546001600160801b03808216606080860191909152600160801b92839004821660808087019190915288519081018952604b548084168252849004831697810197909752604c54808316988801989098529190960490951694840194909452604e5491519093429261360192909116614f47565b11156136455760405162461bcd60e51b815260206004820152601360248201527210db185a5b4819195b185e481b9bdd081b595d606a1b6044820152606401610a72565b80602001516001600160801b031682608001516001600160801b031611156136af5760405162461bcd60e51b815260206004820152601760248201527f51756575652070656e64696e67206c69717569646974790000000000000000006044820152606401610a72565b81516001600160a01b031633146136f85760405162461bcd60e51b815260206004820152600d60248201526c2737ba103932b8bab2b9ba32b960991b6044820152606401610a72565b60208201511561373c5760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606401610a72565b6000848152604d60205260409020805460ff60a01b1916600160a01b179055606082015161379c906120fb906001600160801b03167f000000000000000000000000000000000000000000000000000000000000000660ff1660126132a7565b81604001516137ab91906150be565b604c80546001600160801b0319166001600160801b03928316179055606083015160405191168152849033907f2d43eb174787155132b52ddb6b346e2dca99302eac3df4466dbeff953d3c84d19060200160405180910390a361384082606001516001600160801b03167f000000000000000000000000000000000000000000000000000000000000000660ff1660126132a7565b949350505050565b600061385261443b565b6041549091501561199c57600081116138ad5760405162461bcd60e51b815260206004820152601d60248201527f546f6f206d616e79206f75747374616e64696e672072657175657374730000006044820152606401610a72565b600061393082603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061392a9190614ef6565b906147a0565b9050604154670de0b6b3a7640000821161395b5761395682670de0b6b3a7640000614ecd565b61396d565b61396d670de0b6b3a764000083614ecd565b1115610ce25760405162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f7200006044820152606401610a72565b6001600160a01b03811660009081526035602052604090205460ff16613a235760405162461bcd60e51b815260206004820152601960248201527f5374726174656779206973206e6f7420737570706f72746564000000000000006044820152606401610a72565b6000819050806001600160a01b031663853828b66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613a6357600080fd5b505af1158015613a77573d6000803e3d6000fd5b505050506110f261330b565b6001600160a01b038116613ad95760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f7220697320616464726573732830290000000000006044820152606401610a72565b61199c816147c1565b60007f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316826001600160a01b031614613b2557506000919050565b6040516370a0823160e01b815230600482015282906001600160a01b038216906370a0823190602401602060405180830381865afa158015613b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8f9190614ef6565b60365490925060005b81811015613cb457600060368281548110613bb557613bb5614ea1565b60009182526020909120015460405163551c457b60e11b81526001600160a01b0388811660048301529091169150819063aa388af690602401602060405180830381865afa158015613c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2f9190614f25565b15613cab57604051632fa8a91360e11b81526001600160a01b038781166004830152821690635f51522690602401602060405180830381865afa158015613c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c9e9190614ef6565b613ca89086614f47565b94505b50600101613b98565b5060408051608081018252604b546001600160801b03808216808452600160801b9283900482166020850152604c54808316958501869052929092041660608301529091613d029086614f47565b1015613d1357506000949350505050565b805160408201516001600160801b0391821691613d31911686614f47565b613d3b9190614ecd565b95945050505050565b6001600160a01b03851660009081526035602052604090205460ff16613da25760405162461bcd60e51b8152602060048201526013602482015272496e76616c696420746f20537472617465677960681b6044820152606401610a72565b600183148015613db25750600181145b8015613e1657507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031684846000818110613df657613df6614ea1565b9050602002016020810190613e0b9190614be6565b6001600160a01b0316145b613e625760405162461bcd60e51b815260206004820152601760248201527f4f6e6c7920617373657420697320737570706f727465640000000000000000006044820152606401610a72565b613e6a614828565b82826000818110613e7d57613e7d614ea1565b905060200201351115613ed25760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682061737365747320617661696c61626c6500000000006044820152606401610a72565b613f298583836000818110613ee957613ee9614ea1565b905060200201357f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03166130e09092919063ffffffff16565b846001600160a01b031663de5f62686040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613f6457600080fd5b505af1158015613f78573d6000803e3d6000fd5b505050505050505050565b60006001600160801b038211156130dc5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610a72565b6050546001600160a01b0316806140005750565b600061400a614828565b905080600003614018575050565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015614062573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140869190614ef6565b905060006140cf7f000000000000000000000000000000000000000000000000000000000000000660ff1660126140c86039548661493690919063ffffffff16565b91906132a7565b90508083116140de5750505050565b60006140ea8285614ecd565b9050846141216001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481682846130e0565b6040516311f9fbc960e21b81526001600160a01b038216906347e7ef249061416f907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48908690600401614f5a565b600060405180830381600087803b15801561418957600080fd5b505af115801561419d573d6000803e3d6000fd5b5050604080516001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811682528a1660208201529081018590527f41b99659f6ba0803f444aff29e5bf6e26dd86a3219aff92119d69710a956ba8d9250606001905060405180910390a1505050505050565b6001600160a01b03851660009081526035602052604090205460ff166142755760405162461bcd60e51b8152602060048201526015602482015274496e76616c69642066726f6d20537472617465677960581b6044820152606401610a72565b8281146142c45760405162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d61746368000000000000006044820152606401610a72565b8260005b8181101561439357866001600160a01b031663d9caed12898888858181106142f2576142f2614ea1565b90506020020160208101906143079190614be6565b87878681811061431957614319614ea1565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561437057600080fd5b505af1158015614384573d6000803e3d6000fd5b505050508060010190506142c8565b5061439c61330b565b5050505050505050565b60365460005b8181101561443257603681815481106143c7576143c7614ea1565b60009182526020822001546040805163429c145b60e11b815290516001600160a01b039092169263853828b69260048084019382900301818387803b15801561440f57600080fd5b505af1158015614423573d6000803e3d6000fd5b505050508060010190506143ac565b50610ce261330b565b6000610c2360127f000000000000000000000000000000000000000000000000000000000000000660ff166140c87f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48613ae2565b6000806000603c60009054906101000a90046001600160a01b03166001600160a01b031663e696393a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156144e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061450b9190614ef6565b905060006145198287614ecd565b604f54909150600090614535906001600160401b031642614ecd565b604f54600160c01b90046001600160401b031694509050801580614557575081155b8061456157508587115b8061457357506001600160401b034210155b15614584576000945050505061465b565b61458e8787614ecd565b604f54909550600160401b90046001600160401b031660018111156145f3576145cb856145bc836002614f95565b6145c69089614f73565b61494b565b94506145e0856145db8389614f73565b614662565b94506145f0866145db8488614f95565b95505b604f54614634908790670de0b6b3a764000090600160801b90046001600160401b03166146208688614f95565b61462a9190614f95565b6145db9190614f73565b955061465486670de0b6b3a764000061462a66470de4df82000087614f95565b9550505050505b9250929050565b60008183106146715781613304565b5090919050565b60006146cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661495a9092919063ffffffff16565b8051909150156110f257808060200190518101906146eb9190614f25565b6110f25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a72565b6040516001600160a01b03808516602483015283166044820152606481018290526147829085906323b872dd60e01b906084016130ff565b50505050565b60006133048284614f95565b60006133048284614f73565b6000806147b584670de0b6b3a7640000614788565b90506138408184614794565b806001600160a01b03166147e16000805160206151718339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a360008051602061517183398151915255565b60408051608081018252604b546001600160801b03808216808452600160801b9283900482166020850152604c54808316958501869052929092041660608301526000928391614878919061509f565b6040516370a0823160e01b81523060048201526001600160801b039190911691506000906001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa1580156148ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149119190614ef6565b9050818111614924576000935050505090565b61492e8282614ecd565b935050505090565b60006133048383670de0b6b3a7640000614969565b60008183116146715781613304565b60606138408484600085614982565b6000806149768585614788565b9050613d3b8184614794565b6060824710156149e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a72565b843b614a315760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a72565b600080866001600160a01b03168587604051614a4d9190615101565b60006040518083038185875af1925050503d8060008114614a8a576040519150601f19603f3d011682016040523d82523d6000602084013e614a8f565b606091505b5091509150614a9f828286614aaa565b979650505050505050565b60608315614ab9575081613304565b825115614ac95782518084602001fd5b8160405162461bcd60e51b8152600401610a72919061511d565b828054828255906000526020600020908101928215614b38579160200282015b82811115614b3857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614b03565b506130dc9291505b808211156130dc5760008155600101614b40565b600060208284031215614b6657600080fd5b5035919050565b80356001600160a01b0381168114614b8457600080fd5b919050565b60008060408385031215614b9c57600080fd5b614ba583614b6d565b946020939093013593505050565b600080600060608486031215614bc857600080fd5b614bd184614b6d565b95602085013595506040909401359392505050565b600060208284031215614bf857600080fd5b61330482614b6d565b602080825282518282018190526000918401906040840190835b81811015614c425783516001600160a01b0316835260209384019390920191600101614c1b565b509095945050505050565b60008083601f840112614c5f57600080fd5b5081356001600160401b03811115614c7657600080fd5b6020830191508360208260051b850101111561465b57600080fd5b60008060208385031215614ca457600080fd5b82356001600160401b03811115614cba57600080fd5b614cc685828601614c4d565b90969095509350505050565b6040808252835190820181905260009060208501906060840190835b81811015614d0c578351835260209384019390920191600101614cee565b5050602093909301939093525092915050565b600080600080600060608688031215614d3757600080fd5b614d4086614b6d565b945060208601356001600160401b03811115614d5b57600080fd5b614d6788828901614c4d565b90955093505060408601356001600160401b03811115614d8657600080fd5b614d9288828901614c4d565b969995985093965092949392505050565b60208082526028908201527f43616c6c6572206973206e6f74207468652053747261746567697374206f722060408201526723b7bb32b93737b960c11b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252600e908201526d10d85c1a5d185b081c185d5cd95960921b604082015260600190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b60208082526015908201527414dd1c985d1959de481b9bdd08185c1c1c9bdd9959605a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115611a5057611a50614eb7565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614f0857600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215614f3757600080fd5b8151801515811461330457600080fd5b80820180821115611a5057611a50614eb7565b6001600160a01b03929092168252602082015260400190565b600082614f9057634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417611a5057611a50614eb7565b6001815b6001841115614fe757808504811115614fcb57614fcb614eb7565b6001841615614fd957908102905b60019390931c928002614fb0565b935093915050565b600082614ffe57506001611a50565b8161500b57506000611a50565b8160018114615021576002811461502b57615047565b6001915050611a50565b60ff84111561503c5761503c614eb7565b50506001821b611a50565b5060208310610133831016604e8410600b841016171561506a575081810a611a50565b6150776000198484614fac565b806000190482111561508b5761508b614eb7565b029392505050565b60006133048383614fef565b6001600160801b038281168282160390811115611a5057611a50614eb7565b6001600160801b038181168382160190811115611a5057611a50614eb7565b60005b838110156150f85781810151838201526020016150e0565b50506000910152565b600082516151138184602087016150dd565b9190910192915050565b602081526000825180602084015261513c8160408501602087016150dd565b601f01601f1916919091016040019291505056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa264697066735822122087f0c7c2ae81c28a8a454740a4486d0445606a5b1d80250b4aef44918d20849664736f6c634300081c0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":[["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",{"internalType":"address","name":"_usdc","type":"address"}]],"compiler_version":"v0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2026-05-10T09:56:13.834393Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60c0604052603d80546001600160a01b0319908116909155603e805482169055603f8054909116905534801561003457600080fd5b5060405161541938038061541983398101604081905261005391610133565b808080806000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610097573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bb9190610163565b905060128160ff1611156101155760405162461bcd60e51b815260206004820152601660248201527f696e76616c696420617373657420646563696d616c7300000000000000000000604482015260640160405180910390fd5b6001600160a01b0390911660805260ff1660a0525061018692505050565b60006020828403121561014557600080fd5b81516001600160a01b038116811461015c57600080fd5b9392505050565b60006020828403121561017557600080fd5b815160ff8116811461015c57600080fd5b60805160a0516151c661025360003960008181610fbb015281816120ac0152818161319201528181613773015281816138170152818161408f01526144440152600081816105870152818161088b01528181610c5801528181610ff9015281816112e80152818161144d0152818161176c0152818161187a01528181612ca1015281816132630152818161339101528181613ae601528181613dbb01528181613ef2015281816140fa01528181614145015281816141ad0152818161446b01526148a601526151c66000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c8063663e64ce11610220578063ae69f3cb11610130578063c7af3352116100b8578063e6cc543211610087578063e6cc5432146109e5578063ea33b8e4146109f9578063f3f18c3714610a01578063f844443614610a14578063fac5bb9b14610a2757600080fd5b8063c7af3352146109ba578063c9919112146109c2578063d38bfff4146109ca578063d4c3eea0146109dd57600080fd5b8063b9b17f9f116100ff578063b9b17f9f14610975578063bb7a632e1461097d578063c3b2886414610997578063c4d66de81461099f578063c5f00841146109b257600080fd5b8063ae69f3cb14610934578063af14052c14610947578063b2c9336d1461094f578063b4925a201461096257600080fd5b806395b166bc116101b35780639fa1826e116101825780639fa1826e146108f6578063a0712d68146108ff578063a0aead4d14610912578063ab80dafb14610919578063abaa99161461092c57600080fd5b806395b166bc146108685780639be918e61461087b5780639e428552146108bb5780639ee679e8146108ce57600080fd5b80638e510b52116101ef5780638e510b521461079c5780638ec489a2146107a5578063937b2581146107b857806394828ffd1461086057600080fd5b8063663e64ce14610750578063773540b31461076357806378f353a114610776578063840c4c7a1461078957600080fd5b806339ebf8231161031b578063527e83a8116102ae5780635802a1721161027d5780635802a172146106fe578063597c89101461070f5780635d36b190146107225780635f5152261461072a5780636217f3ea1461073d57600080fd5b8063527e83a8146106aa57806353ca9f24146106c4578063570d8e1d146106d857806357bee944146106eb57600080fd5b806345e4213b116102ea57806345e4213b1461063b57806348e30f541461064457806349c1d54d146106655780634d5f46291461067857600080fd5b806339ebf823146105a95780633b8ae397146105ed5780633dbc911f146106005780634530820a1461060857600080fd5b80631a32aad61161039e5780632acada4d1161036d5780632acada4d146104f35780632da845a81461050857806331e19cfa1461051b578063362bd1a31461052357806338d52e0f1461058257600080fd5b80631a32aad6146104ad5780631cfbe7bc146104c05780631edfe3da146104d3578063207134b0146104ea57600080fd5b80631072cbea116103da5780631072cbea14610461578063156e29f614610474578063175188e8146104875780631816dd4a1461049a57600080fd5b80630493a0fa1461040c57806309f49bf5146104215780630acbda75146104295780630c340a241461043c575b600080fd5b61041f61041a366004614b54565b610a3a565b005b61041f610af0565b61041f610437366004614b54565b610b60565b610444610c0b565b6040516001600160a01b0390911681526020015b60405180910390f35b61041f61046f366004614b89565b610c28565b61041f610482366004614bb3565b610ce6565b61041f610495366004614be6565b610d59565b61041f6104a8366004614be6565b6110f7565b603c54610444906001600160a01b031681565b61041f6104ce366004614b54565b6111fe565b6104dc60395481565b604051908152602001610458565b6104dc60435481565b6104fb6112c0565b6040516104589190614c01565b61041f610516366004614be6565b611337565b6036546104dc565b604b54604c5461054f916001600160801b0380821692600160801b928390048216928183169291041684565b604080516001600160801b0395861681529385166020850152918416918301919091529091166060820152608001610458565b6104447f000000000000000000000000000000000000000000000000000000000000000081565b6105d66105b7366004614be6565b6035602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610458565b61041f6105fb366004614be6565b6113a9565b61041f6115bc565b61062b610616366004614be6565b60496020526000908152604090205460ff1681565b6040519015158152602001610458565b6104dc604e5481565b610657610652366004614c91565b611632565b604051610458929190614cd2565b604254610444906001600160a01b031681565b604f5461069290600160c01b90046001600160401b031681565b6040516001600160401b039091168152602001610458565b604f5461069290600160801b90046001600160401b031681565b60375461062b90600160a01b900460ff1681565b603f54610444906001600160a01b031681565b61041f6106f9366004614be6565b6117a8565b603c546001600160a01b0316610444565b61041f61071d366004614be6565b61195b565b61041f61199f565b6104dc610738366004614be6565b611a45565b61041f61074b366004614b54565b611a56565b61041f61075e366004614b54565b611bda565b61041f610771366004614be6565b611c33565b604f54610692906001600160401b031681565b61041f610797366004614d1f565b611ca5565b6104dc60415481565b61041f6107b3366004614b54565b611d2c565b6108196107c6366004614b54565b604d60205260009081526040902080546001909101546001600160a01b03821691600160a01b810460ff1691600160a81b90910464ffffffffff16906001600160801b0380821691600160801b90041685565b604080516001600160a01b039096168652931515602086015264ffffffffff909216928401929092526001600160801b03918216606084015216608082015260a001610458565b61041f611de1565b61041f610876366004614be6565b611e51565b61062b610889366004614be6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b61041f6108c9366004614be6565b611f18565b6108e16108dc366004614b54565b611f8a565b60408051928352602083019190915201610458565b6104dc603a5481565b61041f61090d366004614b54565b6122ca565b60016104dc565b61041f610927366004614b54565b61233b565b61041f61248a565b61041f610942366004614d1f565b612502565b61041f61257e565b61041f61095d366004614b54565b612639565b61041f610970366004614b54565b612692565b61041f6127b0565b604f5461069290600160401b90046001600160401b031681565b6104fb6127b8565b61041f6109ad366004614be6565b61281a565b61041f6129c5565b61062b612a3b565b61041f612a6c565b61041f6109d8366004614be6565b612aac565b6104dc612b50565b60375461062b90600160a81b900460ff1681565b6104dc612b5a565b605154610444906001600160a01b031681565b6104dc610a22366004614b54565b612be9565b605054610444906001600160a01b031681565b603f546001600160a01b0316331480610a565750610a56612a3b565b610a7b5760405162461bcd60e51b8152600401610a7290614da3565b60405180910390fd5b610a83612cda565b50610a8d81613074565b604f80546001600160401b0392909216600160401b0267ffffffffffffffff60401b199092169190911790556040518181527f406e15fbca1d8ded2dbb06765fea3a54f18395c54125a4c9916dd00ea14ee15e906020015b60405180910390a150565b603f546001600160a01b0316331480610b0c5750610b0c612a3b565b610b285760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a01b191690556040517fbc044409505c95b6b851433df96e1beae715c909d8e7c1d6d7ab783300d4e3b990600090a1565b610b68612a3b565b610b845760405162461bcd60e51b8152600401610a7290614deb565b611388811115610bd65760405162461bcd60e51b815260206004820152601760248201527f62617369732063616e6e6f7420657863656564203530250000000000000000006044820152606401610a72565b60438190556040518181527f56287a45051933ea374811b3d5d165033047be5572cac676f7c28b8be4f746c790602001610ae5565b6000610c236000805160206151718339815191525490565b905090565b610c30612a3b565b610c4c5760405162461bcd60e51b8152600401610a7290614deb565b816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603610cc65760405162461bcd60e51b815260206004820152601660248201527513db9b1e481d5b9cdd5c1c1bdc9d195908185cdcd95d60521b6044820152606401610a72565b610ce2610cd1610c0b565b6001600160a01b03841690836130e0565b5050565b603754600160a81b900460ff1615610d105760405162461bcd60e51b8152600401610a7290614e22565b60008051602061515183398151915280546001198101610d425760405162461bcd60e51b8152600401610a7290614e4a565b60028255610d4f84613136565b5060019055505050565b610d61612a3b565b610d7d5760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526035602052604090205460ff16610db55760405162461bcd60e51b8152600401610a7290614e72565b6050546001600160a01b03808316911603610e125760405162461bcd60e51b815260206004820152601d60248201527f53747261746567792069732064656661756c7420666f722061737365740000006044820152606401610a72565b6036548060005b82811015610e6857836001600160a01b031660368281548110610e3e57610e3e614ea1565b6000918252602090912001546001600160a01b031603610e6057809150610e68565b600101610e19565b50818110156110f2576036610e7e600184614ecd565b81548110610e8e57610e8e614ea1565b600091825260209091200154603680546001600160a01b039092169183908110610eba57610eba614ea1565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506036805480610ef957610ef9614ee0565b6001900381819060005260206000200160006101000a8154906001600160a01b03021916905590556000839050806001600160a01b031663853828b66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610f6157600080fd5b505af1158015610f75573d6000803e3d6000fd5b505050506001600160a01b0384166000908152603560209081526040808320805460ff199081169091556049909252822080549091169055610fe26509184e72a00060ff7f00000000000000000000000000000000000000000000000000000000000000001660126132a7565b604051632fa8a91360e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529192508291841690635f51522690602401602060405180830381865afa15801561104d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110719190614ef6565b106110b35760405162461bcd60e51b81526020600482015260126024820152715374726174656779206861732066756e647360701b6044820152606401610a72565b6040516001600160a01b03861681527f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea49060200160405180910390a150505b505050565b6110ff612a3b565b61111b5760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526035602052604090205460ff166111535760405162461bcd60e51b8152600401610a7290614e72565b6001600160a01b03811660009081526049602052604090205460ff16156111b25760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481dda1a5d195b1a5cdd1959606a1b6044820152606401610a72565b6001600160a01b038116600081815260496020526040808220805460ff19166001179055517f47c8c96a5942f094264111c5fe7f6a4fe86efe63254a6fa7afa5fc84f07d58e89190a250565b611206612a3b565b6112225760405162461bcd60e51b8152600401610a7290614deb565b80158061123f5750610258811015801561123f57506213c6808111155b61128b5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c696420636c61696d2064656c617920706572696f640000000000006044820152606401610a72565b604e8190556040518181527fc59f5e32049abab44ddea11021f5abb89422a2f550837afcf25df9fc8d0db6b090602001610ae5565b60408051600180825281830190925260609160009190602080830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061131a5761131a614ea1565b6001600160a01b0390921660209283029190910190910152919050565b61133f612a3b565b61135b5760405162461bcd60e51b8152600401610a7290614deb565b604280546001600160a01b0319166001600160a01b0383169081179091556040519081527f1e4af5ac389e8cde1bdaa6830881b6c987c62a45cfb3b33d27d805cde3b5775090602001610ae5565b6113b1612a3b565b6113cd5760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526035602052604090205460ff16156114365760405162461bcd60e51b815260206004820152601960248201527f537472617465677920616c726561647920617070726f766564000000000000006044820152606401610a72565b60405163551c457b60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015282169063aa388af690602401602060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190614f25565b61150c5760405162461bcd60e51b815260206004820152601f60248201527f4173736574206e6f7420737570706f72746564206279205374726174656779006044820152606401610a72565b6040805180820182526001808252600060208084018281526001600160a01b038716808452603583528684209551865460ff19169015151786559051948401949094556036805493840181559091527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b890910180546001600160a01b0319168317905591519081527f960dd94cbb79169f09a4e445d58b895df2d9bffa5b31055d0932d801724a20d19101610ae5565b603f546001600160a01b03163314806115d857506115d8612a3b565b6115f45760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a81b1916600160a81b1790556040517f71f0e5b62f846a22e0b4d159e516e62fa9c2b8eb570be15f83e67d98a2ee51e090600090a1565b603754606090600090600160a81b900460ff16156116625760405162461bcd60e51b8152600401610a7290614e22565b600080516020615151833981519152805460011981016116945760405162461bcd60e51b8152600401610a7290614e4a565b600282556116a061330b565b50846001600160401b038111156116b9576116b9614f0f565b6040519080825280602002602001820160405280156116e2578160200160208202803683370190505b50935060005b8581101561175e5761171187878381811061170557611705614ea1565b905060200201356134e7565b85828151811061172357611723614ea1565b60200260200101818152505084818151811061174157611741614ea1565b6020026020010151846117549190614f47565b93506001016116e8565b506117936001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633856130e0565b61179b613848565b6001825550509250929050565b603f546001600160a01b03163314806117c457506117c4612a3b565b6117e05760405162461bcd60e51b8152600401610a7290614da3565b6040516001600160a01b03821681527f45a9e715f8779ebeab88d3e8d081fb8b484b7730857e7c4478a95a5b1d8f79489060200160405180910390a16001600160a01b03811615611939576001600160a01b03811660009081526035602052604090205460ff166118635760405162461bcd60e51b8152600401610a7290614e72565b60405163551c457b60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015282169063aa388af690602401602060405180830381865afa1580156118c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ed9190614f25565b6119395760405162461bcd60e51b815260206004820152601f60248201527f4173736574206e6f7420737570706f72746564206279205374726174656779006044820152606401610a72565b605080546001600160a01b0319166001600160a01b0392909216919091179055565b603f546001600160a01b03163314806119775750611977612a3b565b6119935760405162461bcd60e51b8152600401610a7290614da3565b61199c816139bb565b50565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614611a3a5760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b6064820152608401610a72565b611a4333613a83565b565b6000611a5082613ae2565b92915050565b603754600160a81b900460ff1615611a805760405162461bcd60e51b8152600401610a7290614e22565b3360009081526035602052604090205460ff161515600114611adb5760405162461bcd60e51b8152602060048201526014602482015273556e737570706f7274656420737472617465677960601b6044820152606401610a72565b3360009081526049602052604090205460ff161515600114611b3a5760405162461bcd60e51b81526020600482015260186024820152774e6f742077686974656c697374656420737472617465677960401b6044820152606401610a72565b7f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a63382604051611b6b929190614f5a565b60405180910390a1603c54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90611ba59033908590600401614f5a565b600060405180830381600087803b158015611bbf57600080fd5b505af1158015611bd3573d6000803e3d6000fd5b5050505050565b611be2612a3b565b611bfe5760405162461bcd60e51b8152600401610a7290614deb565b60418190556040518181527f95201f9c21f26877223b1ff4073936a6484c35495649e60e55730497aeb60d9390602001610ae5565b611c3b612a3b565b611c575760405162461bcd60e51b8152600401610a7290614deb565b603f80546001600160a01b0319166001600160a01b0383169081179091556040519081527f869e0abd13cc3a975de7b93be3df1cb2255c802b1cead85963cc79d99f131bee90602001610ae5565b603f546001600160a01b0316331480611cc15750611cc1612a3b565b611cdd5760405162461bcd60e51b8152600401610a7290614da3565b60008051602061515183398151915280546001198101611d0f5760405162461bcd60e51b8152600401610a7290614e4a565b60028255611d208787878787613d44565b50600190555050505050565b603f546001600160a01b0316331480611d485750611d48612a3b565b611d645760405162461bcd60e51b8152600401610a7290614da3565b670de0b6b3a7640000811115611dac5760405162461bcd60e51b815260206004820152600d60248201526c496e76616c69642076616c756560981b6044820152606401610a72565b60398190556040518181527f41ecb23a0e7865b25f38c268b7c3012220d822929e9edff07326e89d5bb822b590602001610ae5565b603f546001600160a01b0316331480611dfd5750611dfd612a3b565b611e195760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a81b191690556040517f891ebab18da80ebeeea06b1b1cede098329c4c008906a98370c2ac7a80b571cb90600090a1565b611e59612a3b565b611e755760405162461bcd60e51b8152600401610a7290614deb565b6001600160a01b03811660009081526049602052604090205460ff16611ecf5760405162461bcd60e51b815260206004820152600f60248201526e139bdd081dda1a5d195b1a5cdd1959608a1b6044820152606401610a72565b6001600160a01b038116600081815260496020526040808220805460ff19169055517f0ec40967a61509853550658e51d0e4297f7cba244fe4adc8ba18b5631ac20e2f9190a250565b611f20612a3b565b611f3c5760405162461bcd60e51b8152600401610a7290614deb565b605180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb3b3f5f64ab192e4b5fefde1f51ce9733bbdcf831951543b325aebd49cc27ec490602001610ae5565b6037546000908190600160a81b900460ff1615611fb95760405162461bcd60e51b8152600401610a7290614e22565b60008051602061515183398151915280546001198101611feb5760405162461bcd60e51b8152600401610a7290614e4a565b600282556000851161203f5760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606401610a72565b6000604e54116120915760405162461bcd60e51b815260206004820152601d60248201527f4173796e63207769746864726177616c73206e6f7420656e61626c65640000006044820152606401610a72565b604c54600160801b90046001600160801b031693506120d5857f000000000000000000000000000000000000000000000000000000000000000060ff1660126132a7565b604b546120eb91906001600160801b0316614f47565b92506121006120fb856001614f47565b613f83565b604c80546001600160801b03928316600160801b02921691909117905561212683613f83565b604b80546001600160801b0319166001600160801b03929092169190911790556040805160a081018252338152600060208201524264ffffffffff16918101919091526060810161217687613f83565b6001600160801b0316815260200161218d85613f83565b6001600160801b039081169091526000868152604d602090815260409182902084518154928601518685015164ffffffffff16600160a81b0264ffffffffff60a81b19911515600160a01b026001600160a81b03199095166001600160a01b0393841617949094171692909217815560608501516080909501518416600160801b029490931693909317600190920191909155603c549051632770a7eb60e21b8152911690639dc29fac906122489033908990600401614f5a565b600060405180830381600087803b15801561226257600080fd5b505af1158015612276573d6000803e3d6000fd5b50505050612282613848565b6040805186815260208101859052859133917f38e3d972947cfef94205163d483d6287ef27eb312e20cb8e0b13a49989db232e910160405180910390a3600182555050915091565b603754600160a81b900460ff16156122f45760405162461bcd60e51b8152600401610a7290614e22565b600080516020615151833981519152805460011981016123265760405162461bcd60e51b8152600401610a7290614e4a565b6002825561233383613136565b506001905550565b603754600160a81b900460ff16156123655760405162461bcd60e51b8152600401610a7290614e22565b3360009081526035602052604090205460ff1615156001146123c05760405162461bcd60e51b8152602060048201526014602482015273556e737570706f7274656420737472617465677960601b6044820152606401610a72565b3360009081526049602052604090205460ff16151560011461241f5760405162461bcd60e51b81526020600482015260186024820152774e6f742077686974656c697374656420737472617465677960401b6044820152606401610a72565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968853382604051612450929190614f5a565b60405180910390a1603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990611ba59033908590600401614f5a565b603754600160a81b900460ff16156124b45760405162461bcd60e51b8152600401610a7290614e22565b600080516020615151833981519152805460011981016124e65760405162461bcd60e51b8152600401610a7290614e4a565b600282556124f261330b565b506124fb613fec565b5060019055565b603f546001600160a01b031633148061251e575061251e612a3b565b61253a5760405162461bcd60e51b8152600401610a7290614da3565b6000805160206151518339815191528054600119810161256c5760405162461bcd60e51b8152600401610a7290614e4a565b60028255611d20308888888888614215565b600080516020615151833981519152805460011981016125b05760405162461bcd60e51b8152600401610a7290614e4a565b600282556051546001600160a01b03163314806125d75750603f546001600160a01b031633145b806125e557506125e5612a3b565b6126295760405162461bcd60e51b815260206004820152601560248201527410d85b1b195c881b9bdd08185d5d1a1bdc9a5e9959605a1b6044820152606401610a72565b612631612cda565b505060019055565b612641612a3b565b61265d5760405162461bcd60e51b8152600401610a7290614deb565b603a8190556040518181527f2ec5fb5a3d2703edc461252d92ccd2799c3c74f01d97212b20388207fa17ae4590602001610ae5565b603f546001600160a01b03163314806126ae57506126ae612a3b565b6126ca5760405162461bcd60e51b8152600401610a7290614da3565b6126d2612cda565b5060006301e133806126e5606484614f73565b6126ef9190614f73565b90506127056201518066b1a2bc2ec50000614f73565b8111156127445760405162461bcd60e51b815260206004820152600d60248201526c0a4c2e8ca40e8dede40d0d2ced609b1b6044820152606401610a72565b61274d81613074565b604f80546001600160401b0392909216600160801b0267ffffffffffffffff60801b199092169190911790556040518181527fef46f143af5fead0010484fe7d6ec2e2972420faa76157f5a6075aa72e614cb59060200160405180910390a15050565b61199c61330b565b6060603680548060200260200160405190810160405280929190818152602001828054801561281057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116127f2575b5050505050905090565b612822612a3b565b61283e5760405162461bcd60e51b8152600401610a7290614deb565b600054610100900460ff1680612857575060005460ff16155b6128ba5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a72565b600054610100900460ff161580156128dc576000805461ffff19166101011790555b6001600160a01b03821661292b5760405162461bcd60e51b81526020600482015260166024820152756f546f6b656e2061646472657373206973207a65726f60501b6044820152606401610a72565b603c80546001600160a01b0384166001600160a01b03199091161790556037805461ffff60a01b1916600160a81b1790556000603981905569054b40b1f852bda00000603a55604080519182526020820190819052905161298e91603691614ae3565b50604f805467ffffffffffffffff60401b19166a093a8000000000000000001790558015610ce2576000805461ff00191690555050565b603f546001600160a01b03163314806129e157506129e1612a3b565b6129fd5760405162461bcd60e51b8152600401610a7290614da3565b6037805460ff60a01b1916600160a01b1790556040517f8cff26a5985614b3d30629cc4ab83824bf115aec971b718d8f2f99562032e97290600090a1565b6000612a536000805160206151718339815191525490565b6001600160a01b0316336001600160a01b031614905090565b603f546001600160a01b0316331480612a885750612a88612a3b565b612aa45760405162461bcd60e51b8152600401610a7290614da3565b611a436143a6565b612ab4612a3b565b612ad05760405162461bcd60e51b8152600401610a7290614deb565b612af8817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b0316612b186000805160206151718339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b6000610c2361443b565b6000612be3603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd69190614ef6565b612bde61443b565b61448f565b50919050565b603754600090600160a81b900460ff1615612c165760405162461bcd60e51b8152600401610a7290614e22565b60008051602061515183398151915280546001198101612c485760405162461bcd60e51b8152600401610a7290614e4a565b60028255604b546000858152604d60205260409020600101546001600160801b03600160801b92839004811692909104161115612c8957612c8761330b565b505b612c92846134e7565b9250612cc86001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633856130e0565b612cd0613848565b5060019055919050565b603754600090600160a01b900460ff1615612d295760405162461bcd60e51b815260206004820152600f60248201526e149958985cda5b99c81c185d5cd959608a1b6044820152606401610a72565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015612d73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d979190614ef6565b90506000612da361443b565b905081600003612db65791506130719050565b600080612dc3848461448f565b90925090506000612dd48386614f47565b90508481111580612de457508381115b15612df3575091949350505050565b612e04826001600160401b03614662565b604f805477ffffffffffffffffffffffffffffffff000000000000000016600160c01b6001600160401b039384160267ffffffffffffffff19161742929092169190911790556042546001600160a01b031660008115612f405761271060435486612e6f9190614f95565b612e799190614f73565b90508015612f4057848110612edb5760405162461bcd60e51b815260206004820152602260248201527f466565206d757374206e6f742062652067726561746572207468616e207969656044820152611b1960f21b6064820152608401610a72565b603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990612f0d9085908590600401614f5a565b600060405180830381600087803b158015612f2757600080fd5b505af1158015612f3b573d6000803e3d6000fd5b505050505b604080516001600160a01b0384168152602081018790529081018290527f09516ecf4a8a86e59780a9befc6dee948bc9e60a36e3be68d31ea817ee8d2c809060600160405180910390a1603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130019190614ef6565b83111561306757603c546040516339a7919f60e01b8152600481018590526001600160a01b03909116906339a7919f90602401600060405180830381600087803b15801561304e57600080fd5b505af1158015613062573d6000803e3d6000fd5b505050505b5093955050505050505b90565b60006001600160401b038211156130dc5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608401610a72565b5090565b6110f28363a9059cbb60e01b84846040516024016130ff929190614f5a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614678565b600081116131865760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e20300000006044820152606401610a72565b60006131b782601260ff7f0000000000000000000000000000000000000000000000000000000000000000166132a7565b90507f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688533826040516131ea929190614f5a565b60405180910390a1603c546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906132249033908590600401614f5a565b600060405180830381600087803b15801561323e57600080fd5b505af1158015613252573d6000803e3d6000fd5b5061328d9250506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016905033308561474a565b61329561330b565b50603a548110610ce257610ce2613fec565b6000818311156132d7576132d06132be8385614ecd565b6132c990600a615093565b8590614788565b9350613301565b81831015613301576132fe6132ec8484614ecd565b6132f790600a615093565b8590614794565b93505b50825b9392505050565b60408051608081018252604b546001600160801b03808216808452600160801b92839004821660208501819052604c548084169686019690965292909404166060830152600092839161335d9161509f565b6001600160801b03169050806000036133795760009250505090565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156133e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134049190614ef6565b905060008360400151846020015161341c919061509f565b6001600160801b0316905080821161343957600094505050505090565b60006134458284614ecd565b90508084106134545780613456565b835b955060008686602001516001600160801b03166134739190614f47565b905061347e81613f83565b604b80546001600160801b03928316600160801b0292169190911790556040517fee79a0c43d3993055690b54e074b5153e8bae8d1a872b656dedb64aa8f463333906134d69083908a90918252602082015260400190565b60405180910390a150505050505090565b600080604e541161353a5760405162461bcd60e51b815260206004820152601d60248201527f4173796e63207769746864726177616c73206e6f7420656e61626c65640000006044820152606401610a72565b6000828152604d6020908152604091829020825160a08101845281546001600160a01b038116825260ff600160a01b82041615158285015264ffffffffff600160a81b90910481168286019081526001909301546001600160801b03808216606080860191909152600160801b92839004821660808087019190915288519081018952604b548084168252849004831697810197909752604c54808316988801989098529190960490951694840194909452604e5491519093429261360192909116614f47565b11156136455760405162461bcd60e51b815260206004820152601360248201527210db185a5b4819195b185e481b9bdd081b595d606a1b6044820152606401610a72565b80602001516001600160801b031682608001516001600160801b031611156136af5760405162461bcd60e51b815260206004820152601760248201527f51756575652070656e64696e67206c69717569646974790000000000000000006044820152606401610a72565b81516001600160a01b031633146136f85760405162461bcd60e51b815260206004820152600d60248201526c2737ba103932b8bab2b9ba32b960991b6044820152606401610a72565b60208201511561373c5760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606401610a72565b6000848152604d60205260409020805460ff60a01b1916600160a01b179055606082015161379c906120fb906001600160801b03167f000000000000000000000000000000000000000000000000000000000000000060ff1660126132a7565b81604001516137ab91906150be565b604c80546001600160801b0319166001600160801b03928316179055606083015160405191168152849033907f2d43eb174787155132b52ddb6b346e2dca99302eac3df4466dbeff953d3c84d19060200160405180910390a361384082606001516001600160801b03167f000000000000000000000000000000000000000000000000000000000000000060ff1660126132a7565b949350505050565b600061385261443b565b6041549091501561199c57600081116138ad5760405162461bcd60e51b815260206004820152601d60248201527f546f6f206d616e79206f75747374616e64696e672072657175657374730000006044820152606401610a72565b600061393082603c60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061392a9190614ef6565b906147a0565b9050604154670de0b6b3a7640000821161395b5761395682670de0b6b3a7640000614ecd565b61396d565b61396d670de0b6b3a764000083614ecd565b1115610ce25760405162461bcd60e51b815260206004820152601e60248201527f4261636b696e6720737570706c79206c6971756964697479206572726f7200006044820152606401610a72565b6001600160a01b03811660009081526035602052604090205460ff16613a235760405162461bcd60e51b815260206004820152601960248201527f5374726174656779206973206e6f7420737570706f72746564000000000000006044820152606401610a72565b6000819050806001600160a01b031663853828b66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613a6357600080fd5b505af1158015613a77573d6000803e3d6000fd5b505050506110f261330b565b6001600160a01b038116613ad95760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f7220697320616464726573732830290000000000006044820152606401610a72565b61199c816147c1565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614613b2557506000919050565b6040516370a0823160e01b815230600482015282906001600160a01b038216906370a0823190602401602060405180830381865afa158015613b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8f9190614ef6565b60365490925060005b81811015613cb457600060368281548110613bb557613bb5614ea1565b60009182526020909120015460405163551c457b60e11b81526001600160a01b0388811660048301529091169150819063aa388af690602401602060405180830381865afa158015613c0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2f9190614f25565b15613cab57604051632fa8a91360e11b81526001600160a01b038781166004830152821690635f51522690602401602060405180830381865afa158015613c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c9e9190614ef6565b613ca89086614f47565b94505b50600101613b98565b5060408051608081018252604b546001600160801b03808216808452600160801b9283900482166020850152604c54808316958501869052929092041660608301529091613d029086614f47565b1015613d1357506000949350505050565b805160408201516001600160801b0391821691613d31911686614f47565b613d3b9190614ecd565b95945050505050565b6001600160a01b03851660009081526035602052604090205460ff16613da25760405162461bcd60e51b8152602060048201526013602482015272496e76616c696420746f20537472617465677960681b6044820152606401610a72565b600183148015613db25750600181145b8015613e1657507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031684846000818110613df657613df6614ea1565b9050602002016020810190613e0b9190614be6565b6001600160a01b0316145b613e625760405162461bcd60e51b815260206004820152601760248201527f4f6e6c7920617373657420697320737570706f727465640000000000000000006044820152606401610a72565b613e6a614828565b82826000818110613e7d57613e7d614ea1565b905060200201351115613ed25760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682061737365747320617661696c61626c6500000000006044820152606401610a72565b613f298583836000818110613ee957613ee9614ea1565b905060200201357f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166130e09092919063ffffffff16565b846001600160a01b031663de5f62686040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613f6457600080fd5b505af1158015613f78573d6000803e3d6000fd5b505050505050505050565b60006001600160801b038211156130dc5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610a72565b6050546001600160a01b0316806140005750565b600061400a614828565b905080600003614018575050565b603c54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015614062573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140869190614ef6565b905060006140cf7f000000000000000000000000000000000000000000000000000000000000000060ff1660126140c86039548661493690919063ffffffff16565b91906132a7565b90508083116140de5750505050565b60006140ea8285614ecd565b9050846141216001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001682846130e0565b6040516311f9fbc960e21b81526001600160a01b038216906347e7ef249061416f907f0000000000000000000000000000000000000000000000000000000000000000908690600401614f5a565b600060405180830381600087803b15801561418957600080fd5b505af115801561419d573d6000803e3d6000fd5b5050604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682528a1660208201529081018590527f41b99659f6ba0803f444aff29e5bf6e26dd86a3219aff92119d69710a956ba8d9250606001905060405180910390a1505050505050565b6001600160a01b03851660009081526035602052604090205460ff166142755760405162461bcd60e51b8152602060048201526015602482015274496e76616c69642066726f6d20537472617465677960581b6044820152606401610a72565b8281146142c45760405162461bcd60e51b815260206004820152601960248201527f506172616d65746572206c656e677468206d69736d61746368000000000000006044820152606401610a72565b8260005b8181101561439357866001600160a01b031663d9caed12898888858181106142f2576142f2614ea1565b90506020020160208101906143079190614be6565b87878681811061431957614319614ea1565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561437057600080fd5b505af1158015614384573d6000803e3d6000fd5b505050508060010190506142c8565b5061439c61330b565b5050505050505050565b60365460005b8181101561443257603681815481106143c7576143c7614ea1565b60009182526020822001546040805163429c145b60e11b815290516001600160a01b039092169263853828b69260048084019382900301818387803b15801561440f57600080fd5b505af1158015614423573d6000803e3d6000fd5b505050508060010190506143ac565b50610ce261330b565b6000610c2360127f000000000000000000000000000000000000000000000000000000000000000060ff166140c87f0000000000000000000000000000000000000000000000000000000000000000613ae2565b6000806000603c60009054906101000a90046001600160a01b03166001600160a01b031663e696393a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156144e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061450b9190614ef6565b905060006145198287614ecd565b604f54909150600090614535906001600160401b031642614ecd565b604f54600160c01b90046001600160401b031694509050801580614557575081155b8061456157508587115b8061457357506001600160401b034210155b15614584576000945050505061465b565b61458e8787614ecd565b604f54909550600160401b90046001600160401b031660018111156145f3576145cb856145bc836002614f95565b6145c69089614f73565b61494b565b94506145e0856145db8389614f73565b614662565b94506145f0866145db8488614f95565b95505b604f54614634908790670de0b6b3a764000090600160801b90046001600160401b03166146208688614f95565b61462a9190614f95565b6145db9190614f73565b955061465486670de0b6b3a764000061462a66470de4df82000087614f95565b9550505050505b9250929050565b60008183106146715781613304565b5090919050565b60006146cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661495a9092919063ffffffff16565b8051909150156110f257808060200190518101906146eb9190614f25565b6110f25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a72565b6040516001600160a01b03808516602483015283166044820152606481018290526147829085906323b872dd60e01b906084016130ff565b50505050565b60006133048284614f95565b60006133048284614f73565b6000806147b584670de0b6b3a7640000614788565b90506138408184614794565b806001600160a01b03166147e16000805160206151718339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a360008051602061517183398151915255565b60408051608081018252604b546001600160801b03808216808452600160801b9283900482166020850152604c54808316958501869052929092041660608301526000928391614878919061509f565b6040516370a0823160e01b81523060048201526001600160801b039190911691506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156148ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149119190614ef6565b9050818111614924576000935050505090565b61492e8282614ecd565b935050505090565b60006133048383670de0b6b3a7640000614969565b60008183116146715781613304565b60606138408484600085614982565b6000806149768585614788565b9050613d3b8184614794565b6060824710156149e35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a72565b843b614a315760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a72565b600080866001600160a01b03168587604051614a4d9190615101565b60006040518083038185875af1925050503d8060008114614a8a576040519150601f19603f3d011682016040523d82523d6000602084013e614a8f565b606091505b5091509150614a9f828286614aaa565b979650505050505050565b60608315614ab9575081613304565b825115614ac95782518084602001fd5b8160405162461bcd60e51b8152600401610a72919061511d565b828054828255906000526020600020908101928215614b38579160200282015b82811115614b3857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614b03565b506130dc9291505b808211156130dc5760008155600101614b40565b600060208284031215614b6657600080fd5b5035919050565b80356001600160a01b0381168114614b8457600080fd5b919050565b60008060408385031215614b9c57600080fd5b614ba583614b6d565b946020939093013593505050565b600080600060608486031215614bc857600080fd5b614bd184614b6d565b95602085013595506040909401359392505050565b600060208284031215614bf857600080fd5b61330482614b6d565b602080825282518282018190526000918401906040840190835b81811015614c425783516001600160a01b0316835260209384019390920191600101614c1b565b509095945050505050565b60008083601f840112614c5f57600080fd5b5081356001600160401b03811115614c7657600080fd5b6020830191508360208260051b850101111561465b57600080fd5b60008060208385031215614ca457600080fd5b82356001600160401b03811115614cba57600080fd5b614cc685828601614c4d565b90969095509350505050565b6040808252835190820181905260009060208501906060840190835b81811015614d0c578351835260209384019390920191600101614cee565b5050602093909301939093525092915050565b600080600080600060608688031215614d3757600080fd5b614d4086614b6d565b945060208601356001600160401b03811115614d5b57600080fd5b614d6788828901614c4d565b90955093505060408601356001600160401b03811115614d8657600080fd5b614d9288828901614c4d565b969995985093965092949392505050565b60208082526028908201527f43616c6c6572206973206e6f74207468652053747261746567697374206f722060408201526723b7bb32b93737b960c11b606082015260800190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252600e908201526d10d85c1a5d185b081c185d5cd95960921b604082015260600190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b60208082526015908201527414dd1c985d1959de481b9bdd08185c1c1c9bdd9959605a1b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115611a5057611a50614eb7565b634e487b7160e01b600052603160045260246000fd5b600060208284031215614f0857600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215614f3757600080fd5b8151801515811461330457600080fd5b80820180821115611a5057611a50614eb7565b6001600160a01b03929092168252602082015260400190565b600082614f9057634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417611a5057611a50614eb7565b6001815b6001841115614fe757808504811115614fcb57614fcb614eb7565b6001841615614fd957908102905b60019390931c928002614fb0565b935093915050565b600082614ffe57506001611a50565b8161500b57506000611a50565b8160018114615021576002811461502b57615047565b6001915050611a50565b60ff84111561503c5761503c614eb7565b50506001821b611a50565b5060208310610133831016604e8410600b841016171561506a575081810a611a50565b6150776000198484614fac565b806000190482111561508b5761508b614eb7565b029392505050565b60006133048383614fef565b6001600160801b038281168282160390811115611a5057611a50614eb7565b6001600160801b038181168382160190811115611a5057611a50614eb7565b60005b838110156150f85781810151838201526020016150e0565b50506000910152565b600082516151138184602087016150dd565b9190910192915050565b602081526000825180602084015261513c8160408501602087016150dd565b601f01601f1916919091016040019291505056fe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa264697066735822122087f0c7c2ae81c28a8a454740a4486d0445606a5b1d80250b4aef44918d20849664736f6c634300081c0033000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","name":"OUSDVault","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"paris","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"contracts/vault/VaultInitializer.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title OToken VaultInitializer contract\n * @notice The Vault contract initializes the vault.\n * @author Origin Protocol Inc\n */\n\nimport \"./VaultStorage.sol\";\n\nabstract contract VaultInitializer is VaultStorage {\n    constructor(address _asset) VaultStorage(_asset) {}\n\n    function initialize(address _oToken) external onlyGovernor initializer {\n        require(_oToken != address(0), \"oToken address is zero\");\n\n        oToken = OUSD(_oToken);\n\n        rebasePaused = false;\n        capitalPaused = true;\n\n        // Initial Vault buffer of 0%\n        vaultBuffer = 0;\n        // Initial allocate threshold of 25,000 OUSD\n        autoAllocateThreshold = 25000e18;\n        // Initialize all strategies\n        allStrategies = new address[](0);\n        // Start with drip duration: 7 days\n        dripDuration = 604800;\n    }\n}\n"},{"file_path":"contracts/vault/VaultStorage.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title OToken VaultStorage contract\n * @notice The VaultStorage contract defines the storage for the Vault contracts\n * @author Origin Protocol Inc\n */\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport { IStrategy } from \"../interfaces/IStrategy.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { Governable } from \"../governance/Governable.sol\";\nimport { OUSD } from \"../token/OUSD.sol\";\nimport { Initializable } from \"../utils/Initializable.sol\";\nimport \"../utils/Helpers.sol\";\n\nabstract contract VaultStorage is Initializable, Governable {\n    using SafeERC20 for IERC20;\n\n    event AssetAllocated(address _asset, address _strategy, uint256 _amount);\n    event StrategyApproved(address _addr);\n    event StrategyRemoved(address _addr);\n    event Mint(address _addr, uint256 _value);\n    event Redeem(address _addr, uint256 _value);\n    event CapitalPaused();\n    event CapitalUnpaused();\n    event DefaultStrategyUpdated(address _strategy);\n    event RebasePaused();\n    event RebaseUnpaused();\n    event VaultBufferUpdated(uint256 _vaultBuffer);\n    event AllocateThresholdUpdated(uint256 _threshold);\n    event StrategistUpdated(address _address);\n    event MaxSupplyDiffChanged(uint256 maxSupplyDiff);\n    event YieldDistribution(address _to, uint256 _yield, uint256 _fee);\n    event TrusteeFeeBpsChanged(uint256 _basis);\n    event TrusteeAddressChanged(address _address);\n    event StrategyAddedToMintWhitelist(address indexed strategy);\n    event StrategyRemovedFromMintWhitelist(address indexed strategy);\n    event RebasePerSecondMaxChanged(uint256 rebaseRatePerSecond);\n    event DripDurationChanged(uint256 dripDuration);\n    event OperatorUpdated(address newOperator);\n    event WithdrawalRequested(\n        address indexed _withdrawer,\n        uint256 indexed _requestId,\n        uint256 _amount,\n        uint256 _queued\n    );\n    event WithdrawalClaimed(\n        address indexed _withdrawer,\n        uint256 indexed _requestId,\n        uint256 _amount\n    );\n    event WithdrawalClaimable(uint256 _claimable, uint256 _newClaimable);\n    event WithdrawalClaimDelayUpdated(uint256 _newDelay);\n\n    // Since we are proxy, all state should be uninitalized.\n    // Since this storage contract does not have logic directly on it\n    // we should not be checking for to see if these variables can be constant.\n    // slither-disable-start uninitialized-state\n    // slither-disable-start constable-states\n\n    /// @dev mapping of supported vault assets to their configuration\n    uint256 private _deprecated_assets;\n    /// @dev list of all assets supported by the vault.\n    address[] private _deprecated_allAssets;\n\n    // Strategies approved for use by the Vault\n    struct Strategy {\n        bool isSupported;\n        uint256 _deprecated; // Deprecated storage slot\n    }\n    /// @dev mapping of strategy contracts to their configuration\n    mapping(address => Strategy) public strategies;\n    /// @dev list of all vault strategies\n    address[] internal allStrategies;\n\n    /// @notice Address of the Oracle price provider contract\n    address private _deprecated_priceProvider;\n    /// @notice pause rebasing if true\n    bool public rebasePaused;\n    /// @notice pause operations that change the OToken supply.\n    /// eg mint, redeem, allocate, mint/burn for strategy\n    bool public capitalPaused;\n    /// @notice Redemption fee in basis points. eg 50 = 0.5%\n    uint256 private _deprecated_redeemFeeBps;\n    /// @notice Percentage of assets to keep in Vault to handle (most) withdrawals. 100% = 1e18.\n    uint256 public vaultBuffer;\n    /// @notice OToken mints over this amount automatically allocate funds. 18 decimals.\n    uint256 public autoAllocateThreshold;\n    /// @dev Deprecated. Was the auto-rebase trigger threshold for mint/redeem.\n    ///      Storage slot retained for proxy compatibility; no longer read or written.\n    uint256 internal __deprecatedRebaseThreshold;\n\n    /// @dev Address of the OToken token. eg OUSD or OETH.\n    OUSD public oToken;\n\n    /// @dev Address of the contract responsible for post rebase syncs with AMMs\n    address private _deprecated_rebaseHooksAddr = address(0);\n\n    /// @dev Deprecated: Address of Uniswap\n    address private _deprecated_uniswapAddr = address(0);\n\n    /// @notice Address of the Strategist\n    address public strategistAddr = address(0);\n\n    /// @notice Mapping of asset address to the Strategy that they should automatically\n    // be allocated to\n    uint256 private _deprecated_assetDefaultStrategies;\n\n    /// @notice Max difference between total supply and total value of assets. 18 decimals.\n    uint256 public maxSupplyDiff;\n\n    /// @notice Trustee contract that can collect a percentage of yield\n    address public trusteeAddress;\n\n    /// @notice Amount of yield collected in basis points. eg 2000 = 20%\n    uint256 public trusteeFeeBps;\n\n    /// @dev Deprecated: Tokens that should be swapped for stablecoins\n    address[] private _deprecated_swapTokens;\n\n    /// @notice Metapool strategy that is allowed to mint/burn OTokens without changing collateral\n\n    address private _deprecated_ousdMetaStrategy;\n\n    /// @notice How much OTokens are currently minted by the strategy\n    int256 private _deprecated_netOusdMintedForStrategy;\n\n    /// @notice How much net total OTokens are allowed to be minted by all strategies\n    uint256 private _deprecated_netOusdMintForStrategyThreshold;\n\n    uint256 private _deprecated_swapConfig;\n\n    // List of strategies that can mint oTokens directly\n    // Used in OETHBaseVaultCore\n    mapping(address => bool) public isMintWhitelistedStrategy;\n\n    /// @notice Address of the Dripper contract that streams harvested rewards to the Vault\n    /// @dev The vault is proxied so needs to be set with setDripper against the proxy contract.\n    address private _deprecated_dripper;\n\n    /// Withdrawal Queue Storage /////\n\n    struct WithdrawalQueueMetadata {\n        // cumulative total of all withdrawal requests included the ones that have already been claimed\n        uint128 queued;\n        // cumulative total of all the requests that can be claimed including the ones that have already been claimed\n        uint128 claimable;\n        // total of all the requests that have been claimed\n        uint128 claimed;\n        // index of the next withdrawal request starting at 0\n        uint128 nextWithdrawalIndex;\n    }\n\n    /// @notice Global metadata for the withdrawal queue including:\n    /// queued - cumulative total of all withdrawal requests included the ones that have already been claimed\n    /// claimable - cumulative total of all the requests that can be claimed including the ones already claimed\n    /// claimed - total of all the requests that have been claimed\n    /// nextWithdrawalIndex - index of the next withdrawal request starting at 0\n    WithdrawalQueueMetadata public withdrawalQueueMetadata;\n\n    struct WithdrawalRequest {\n        address withdrawer;\n        bool claimed;\n        uint40 timestamp; // timestamp of the withdrawal request\n        // Amount of oTokens to redeem. eg OETH\n        uint128 amount;\n        // cumulative total of all withdrawal requests including this one.\n        // this request can be claimed when this queued amount is less than or equal to the queue's claimable amount.\n        uint128 queued;\n    }\n\n    /// @notice Mapping of withdrawal request indices to the user withdrawal request data\n    mapping(uint256 => WithdrawalRequest) public withdrawalRequests;\n\n    /// @notice Sets a minimum delay that is required to elapse between\n    ///     requesting async withdrawals and claiming the request.\n    ///     When set to 0 async withdrawals are disabled.\n    uint256 public withdrawalClaimDelay;\n\n    /// @notice Time in seconds that the vault last rebased yield.\n    uint64 public lastRebase;\n\n    /// @notice Automatic rebase yield calculations. In seconds. Set to 0 or 1 to disable.\n    uint64 public dripDuration;\n\n    /// @notice max rebase percentage per second\n    ///   Can be used to set maximum yield of the protocol,\n    ///   spreading out yield over time\n    uint64 public rebasePerSecondMax;\n\n    /// @notice target rebase rate limit, based on past rates and funds available.\n    uint64 public rebasePerSecondTarget;\n\n    uint256 internal constant MAX_REBASE = 0.02 ether;\n    uint256 internal constant MAX_REBASE_PER_SECOND =\n        uint256(0.05 ether) / 1 days;\n\n    /// @notice Default strategy for asset\n    address public defaultStrategy;\n\n    /// @notice Address authorized to call `rebase()` directly. The Governor\n    ///         and Strategist are always allowed in addition to this address.\n    address public operatorAddr;\n\n    // For future use\n    uint256[41] private __gap;\n\n    /// @notice Index of WETH asset in allAssets array\n    /// Legacy OETHVaultCore code, relocated here for vault consistency.\n    uint256 private _deprecated_wethAssetIndex;\n\n    /// @dev Address of the asset (eg. WETH or USDC)\n    address public immutable asset;\n    uint8 internal immutable assetDecimals;\n\n    // slither-disable-end constable-states\n    // slither-disable-end uninitialized-state\n\n    constructor(address _asset) {\n        uint8 _decimals = IERC20Metadata(_asset).decimals();\n        require(_decimals <= 18, \"invalid asset decimals\");\n        asset = _asset;\n        assetDecimals = _decimals;\n    }\n\n    /// @notice Deprecated: use `oToken()` instead.\n    function oUSD() external view returns (OUSD) {\n        return oToken;\n    }\n}\n"},{"file_path":"contracts/interfaces/IBasicToken.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBasicToken {\n    function symbol() external view returns (string memory);\n\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an 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 *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128) {\n        require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return int128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64) {\n        require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return int64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32) {\n        require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return int32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16) {\n        require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return int16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8) {\n        require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return int8(value);\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"},{"file_path":"@openzeppelin/contracts/utils/math/SafeMath.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"},{"file_path":"contracts/governance/Governable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title Base for contracts that are managed by the Origin Protocol's Governor.\n * @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change\n *      from owner to governor and renounce methods removed. Does not use\n *      Context.sol like Ownable.sol does for simplification.\n * @author Origin Protocol Inc\n */\nabstract contract Governable {\n    // Storage position of the owner and pendingOwner of the contract\n    // keccak256(\"OUSD.governor\");\n    bytes32 private constant governorPosition =\n        0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a;\n\n    // keccak256(\"OUSD.pending.governor\");\n    bytes32 private constant pendingGovernorPosition =\n        0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db;\n\n    // keccak256(\"OUSD.reentry.status\");\n    bytes32 private constant reentryStatusPosition =\n        0x53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535;\n\n    // See OpenZeppelin ReentrancyGuard implementation\n    uint256 constant _NOT_ENTERED = 1;\n    uint256 constant _ENTERED = 2;\n\n    event PendingGovernorshipTransfer(\n        address indexed previousGovernor,\n        address indexed newGovernor\n    );\n\n    event GovernorshipTransferred(\n        address indexed previousGovernor,\n        address indexed newGovernor\n    );\n\n    /**\n     * @notice Returns the address of the current Governor.\n     */\n    function governor() public view returns (address) {\n        return _governor();\n    }\n\n    /**\n     * @dev Returns the address of the current Governor.\n     */\n    function _governor() internal view returns (address governorOut) {\n        bytes32 position = governorPosition;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            governorOut := sload(position)\n        }\n    }\n\n    /**\n     * @dev Returns the address of the pending Governor.\n     */\n    function _pendingGovernor()\n        internal\n        view\n        returns (address pendingGovernor)\n    {\n        bytes32 position = pendingGovernorPosition;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            pendingGovernor := sload(position)\n        }\n    }\n\n    /**\n     * @dev Throws if called by any account other than the Governor.\n     */\n    modifier onlyGovernor() {\n        require(isGovernor(), \"Caller is not the Governor\");\n        _;\n    }\n\n    /**\n     * @notice Returns true if the caller is the current Governor.\n     */\n    function isGovernor() public view returns (bool) {\n        return msg.sender == _governor();\n    }\n\n    function _setGovernor(address newGovernor) internal {\n        emit GovernorshipTransferred(_governor(), newGovernor);\n\n        bytes32 position = governorPosition;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(position, newGovernor)\n        }\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and make it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        bytes32 position = reentryStatusPosition;\n        uint256 _reentry_status;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            _reentry_status := sload(position)\n        }\n\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_reentry_status != _ENTERED, \"Reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(position, _ENTERED)\n        }\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(position, _NOT_ENTERED)\n        }\n    }\n\n    function _setPendingGovernor(address newGovernor) internal {\n        bytes32 position = pendingGovernorPosition;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(position, newGovernor)\n        }\n    }\n\n    /**\n     * @notice Transfers Governance of the contract to a new account (`newGovernor`).\n     * Can only be called by the current Governor. Must be claimed for this to complete\n     * @param _newGovernor Address of the new Governor\n     */\n    function transferGovernance(address _newGovernor) external onlyGovernor {\n        _setPendingGovernor(_newGovernor);\n        emit PendingGovernorshipTransfer(_governor(), _newGovernor);\n    }\n\n    /**\n     * @notice Claim Governance of the contract to a new account (`newGovernor`).\n     * Can only be called by the new Governor.\n     */\n    function claimGovernance() external {\n        require(\n            msg.sender == _pendingGovernor(),\n            \"Only the pending Governor can complete the claim\"\n        );\n        _changeGovernor(msg.sender);\n    }\n\n    /**\n     * @dev Change Governance of the contract to a new account (`newGovernor`).\n     * @param _newGovernor Address of the new Governor\n     */\n    function _changeGovernor(address _newGovernor) internal {\n        require(_newGovernor != address(0), \"New Governor is address(0)\");\n        _setGovernor(_newGovernor);\n    }\n}\n"},{"file_path":"contracts/interfaces/IStrategy.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title Platform interface to integrate with lending platform like Compound, AAVE etc.\n */\ninterface IStrategy {\n    /**\n     * @dev Deposit the given asset to platform\n     * @param _asset asset address\n     * @param _amount Amount to deposit\n     */\n    function deposit(address _asset, uint256 _amount) external;\n\n    /**\n     * @dev Deposit the entire balance of all supported assets in the Strategy\n     *      to the platform\n     */\n    function depositAll() external;\n\n    /**\n     * @dev Withdraw given asset from Lending platform\n     */\n    function withdraw(\n        address _recipient,\n        address _asset,\n        uint256 _amount\n    ) external;\n\n    /**\n     * @dev Liquidate all assets in strategy and return them to Vault.\n     */\n    function withdrawAll() external;\n\n    /**\n     * @dev Returns the current balance of the given asset.\n     */\n    function checkBalance(address _asset)\n        external\n        view\n        returns (uint256 balance);\n\n    /**\n     * @dev Returns bool indicating whether strategy supports asset.\n     */\n    function supportsAsset(address _asset) external view returns (bool);\n\n    /**\n     * @dev Collect reward tokens from the Strategy.\n     */\n    function collectRewardTokens() external;\n\n    /**\n     * @dev The address array of the reward tokens for the Strategy.\n     */\n    function getRewardTokenAddresses() external view returns (address[] memory);\n\n    function harvesterAddress() external view returns (address);\n\n    function transferToken(address token, uint256 amount) external;\n\n    function setRewardTokenAddresses(address[] calldata _rewardTokenAddresses)\n        external;\n}\n"},{"file_path":"contracts/interfaces/IVault.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport { VaultStorage } from \"../vault/VaultStorage.sol\";\n\ninterface IVault {\n    // slither-disable-start constable-states\n\n    event AssetAllocated(address _asset, address _strategy, uint256 _amount);\n    event StrategyApproved(address _addr);\n    event StrategyRemoved(address _addr);\n    event Mint(address _addr, uint256 _value);\n    event Redeem(address _addr, uint256 _value);\n    event CapitalPaused();\n    event CapitalUnpaused();\n    event DefaultStrategyUpdated(address _strategy);\n    event RebasePaused();\n    event RebaseUnpaused();\n    event VaultBufferUpdated(uint256 _vaultBuffer);\n    event AllocateThresholdUpdated(uint256 _threshold);\n    event StrategistUpdated(address _address);\n    event MaxSupplyDiffChanged(uint256 maxSupplyDiff);\n    event YieldDistribution(address _to, uint256 _yield, uint256 _fee);\n    event TrusteeFeeBpsChanged(uint256 _basis);\n    event TrusteeAddressChanged(address _address);\n    event StrategyAddedToMintWhitelist(address indexed strategy);\n    event StrategyRemovedFromMintWhitelist(address indexed strategy);\n    event RebasePerSecondMaxChanged(uint256 rebaseRatePerSecond);\n    event DripDurationChanged(uint256 dripDuration);\n    event WithdrawalRequested(\n        address indexed _withdrawer,\n        uint256 indexed _requestId,\n        uint256 _amount,\n        uint256 _queued\n    );\n    event WithdrawalClaimed(\n        address indexed _withdrawer,\n        uint256 indexed _requestId,\n        uint256 _amount\n    );\n    event WithdrawalClaimable(uint256 _claimable, uint256 _newClaimable);\n    event WithdrawalClaimDelayUpdated(uint256 _newDelay);\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 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 setStrategistAddr(address _address) external;\n\n    function strategistAddr() external view returns (address);\n\n    function setOperatorAddr(address _operator) external;\n\n    function operatorAddr() 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 approveStrategy(address _addr) external;\n\n    function removeStrategy(address _addr) external;\n\n    function setDefaultStrategy(address _strategy) external;\n\n    function defaultStrategy() external view 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 withdrawAllFromStrategy(address _strategyAddr) external;\n\n    function withdrawAllFromStrategies() external;\n\n    function withdrawFromStrategy(\n        address _strategyFromAddress,\n        address[] calldata _assets,\n        uint256[] calldata _amounts\n    ) external;\n\n    function depositToStrategy(\n        address _strategyToAddress,\n        address[] calldata _assets,\n        uint256[] calldata _amounts\n    ) external;\n\n    // VaultCore.sol\n    function mint(uint256 _amount) external;\n\n    function mintForStrategy(uint256 _amount) external;\n\n    function burnForStrategy(uint256 _amount) external;\n\n    function allocate() external;\n\n    function rebase() external;\n\n    function totalValue() external view returns (uint256 value);\n\n    function checkBalance(address _asset) external view returns (uint256);\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 getAllStrategies() external view returns (address[] memory);\n\n    function strategies(address _addr)\n        external\n        view\n        returns (VaultStorage.Strategy memory);\n\n    /// @notice Deprecated: use `asset()` instead.\n    function isSupportedAsset(address _asset) external view returns (bool);\n\n    function asset() external view returns (address);\n\n    function oToken() external view returns (address);\n\n    function initialize(address) external;\n\n    function addWithdrawalQueueLiquidity() external;\n\n    function requestWithdrawal(uint256 _amount)\n        external\n        returns (uint256 requestId, uint256 queued);\n\n    function claimWithdrawal(uint256 requestId)\n        external\n        returns (uint256 amount);\n\n    function claimWithdrawals(uint256[] memory requestIds)\n        external\n        returns (uint256[] memory amounts, uint256 totalAmount);\n\n    function withdrawalQueueMetadata()\n        external\n        view\n        returns (VaultStorage.WithdrawalQueueMetadata memory);\n\n    function withdrawalRequests(uint256 requestId)\n        external\n        view\n        returns (VaultStorage.WithdrawalRequest memory);\n\n    function addStrategyToMintWhitelist(address strategyAddr) external;\n\n    function removeStrategyFromMintWhitelist(address strategyAddr) external;\n\n    function isMintWhitelistedStrategy(address strategyAddr)\n        external\n        view\n        returns (bool);\n\n    function withdrawalClaimDelay() external view returns (uint256);\n\n    function setWithdrawalClaimDelay(uint256 newDelay) external;\n\n    function lastRebase() external view returns (uint64);\n\n    function dripDuration() external view returns (uint64);\n\n    function setDripDuration(uint256 _dripDuration) external;\n\n    function rebasePerSecondMax() external view returns (uint64);\n\n    function setRebaseRateMax(uint256 yearlyApr) external;\n\n    function rebasePerSecondTarget() external view returns (uint64);\n\n    function previewYield() external view returns (uint256 yield);\n\n    // slither-disable-end constable-states\n}\n"},{"file_path":"contracts/token/OUSD.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title OUSD Token Contract\n * @dev ERC20 compatible contract for OUSD\n * @dev Implements an elastic supply\n * @author Origin Protocol Inc\n */\nimport { IVault } from \"../interfaces/IVault.sol\";\nimport { Governable } from \"../governance/Governable.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\ncontract OUSD is Governable {\n    using SafeCast for int256;\n    using SafeCast for uint256;\n\n    /// @dev Event triggered when the supply changes\n    /// @param totalSupply Updated token total supply\n    /// @param rebasingCredits Updated token rebasing credits\n    /// @param rebasingCreditsPerToken Updated token rebasing credits per token\n    event TotalSupplyUpdatedHighres(\n        uint256 totalSupply,\n        uint256 rebasingCredits,\n        uint256 rebasingCreditsPerToken\n    );\n    /// @dev Event triggered when an account opts in for rebasing\n    /// @param account Address of the account\n    event AccountRebasingEnabled(address account);\n    /// @dev Event triggered when an account opts out of rebasing\n    /// @param account Address of the account\n    event AccountRebasingDisabled(address account);\n    /// @dev Emitted when `value` tokens are moved from one account `from` to\n    ///      another `to`.\n    /// @param from Address of the account tokens are moved from\n    /// @param to Address of the account tokens are moved to\n    /// @param value Amount of tokens transferred\n    event Transfer(address indexed from, address indexed to, uint256 value);\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    /// @param owner Address of the owner approving allowance\n    /// @param spender Address of the spender allowance is granted to\n    /// @param value Amount of tokens spender can transfer\n    event Approval(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n    /// @dev Yield resulting from {changeSupply} that a `source` account would\n    ///      receive is directed to `target` account.\n    /// @param source Address of the source forwarding the yield\n    /// @param target Address of the target receiving the yield\n    event YieldDelegated(address source, address target);\n    /// @dev Yield delegation from `source` account to the `target` account is\n    ///      suspended.\n    /// @param source Address of the source suspending yield forwarding\n    /// @param target Address of the target no longer receiving yield from `source`\n    ///        account\n    event YieldUndelegated(address source, address target);\n\n    enum RebaseOptions {\n        NotSet,\n        StdNonRebasing,\n        StdRebasing,\n        YieldDelegationSource,\n        YieldDelegationTarget\n    }\n\n    uint256[154] private _gap; // Slots to align with deployed contract\n    uint256 private constant MAX_SUPPLY = type(uint128).max;\n    /// @dev The amount of tokens in existence\n    uint256 public totalSupply;\n    mapping(address => mapping(address => uint256)) private allowances;\n    /// @dev The vault with privileges to execute {mint}, {burn}\n    ///     and {changeSupply}\n    address public vaultAddress;\n    mapping(address => uint256) internal creditBalances;\n    // the 2 storage variables below need trailing underscores to not name collide with public functions\n    uint256 private rebasingCredits_; // Sum of all rebasing credits (creditBalances for rebasing accounts)\n    uint256 private rebasingCreditsPerToken_;\n    /// @dev The amount of tokens that are not rebasing - receiving yield\n    uint256 public nonRebasingSupply;\n    mapping(address => uint256) internal alternativeCreditsPerToken;\n    /// @dev A map of all addresses and their respective RebaseOptions\n    mapping(address => RebaseOptions) public rebaseState;\n    mapping(address => uint256) private __deprecated_isUpgraded;\n    /// @dev A map of addresses that have yields forwarded to. This is an\n    ///      inverse mapping of {yieldFrom}\n    /// Key Account forwarding yield\n    /// Value Account receiving yield\n    mapping(address => address) public yieldTo;\n    /// @dev A map of addresses that are receiving the yield. This is an\n    ///      inverse mapping of {yieldTo}\n    /// Key Account receiving yield\n    /// Value Account forwarding yield\n    mapping(address => address) public yieldFrom;\n\n    uint256 private constant RESOLUTION_INCREASE = 1e9;\n    uint256[34] private __gap; // including below gap totals up to 200\n\n    /// @dev Verifies that the caller is the Governor or Strategist.\n    modifier onlyGovernorOrStrategist() {\n        require(\n            isGovernor() || msg.sender == IVault(vaultAddress).strategistAddr(),\n            \"Caller is not the Strategist or Governor\"\n        );\n        _;\n    }\n\n    /// @dev Initializes the contract and sets necessary variables.\n    /// @param _vaultAddress Address of the vault contract\n    /// @param _initialCreditsPerToken The starting rebasing credits per token.\n    function initialize(address _vaultAddress, uint256 _initialCreditsPerToken)\n        external\n        onlyGovernor\n    {\n        require(_vaultAddress != address(0), \"Zero vault address\");\n        require(vaultAddress == address(0), \"Already initialized\");\n\n        rebasingCreditsPerToken_ = _initialCreditsPerToken;\n        vaultAddress = _vaultAddress;\n    }\n\n    /// @dev Returns the symbol of the token, a shorter version\n    ///      of the name.\n    function symbol() external pure virtual returns (string memory) {\n        return \"OUSD\";\n    }\n\n    /// @dev Returns the name of the token.\n    function name() external pure virtual returns (string memory) {\n        return \"Origin Dollar\";\n    }\n\n    /// @dev Returns the number of decimals used to get its user representation.\n    function decimals() external pure virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev Verifies that the caller is the Vault contract\n     */\n    modifier onlyVault() {\n        require(vaultAddress == msg.sender, \"Caller is not the Vault\");\n        _;\n    }\n\n    /**\n     * @return High resolution rebasingCreditsPerToken\n     */\n    function rebasingCreditsPerTokenHighres() external view returns (uint256) {\n        return rebasingCreditsPerToken_;\n    }\n\n    /**\n     * @return Low resolution rebasingCreditsPerToken\n     */\n    function rebasingCreditsPerToken() external view returns (uint256) {\n        return rebasingCreditsPerToken_ / RESOLUTION_INCREASE;\n    }\n\n    /**\n     * @return High resolution total number of rebasing credits\n     */\n    function rebasingCreditsHighres() external view returns (uint256) {\n        return rebasingCredits_;\n    }\n\n    /**\n     * @return Low resolution total number of rebasing credits\n     */\n    function rebasingCredits() external view returns (uint256) {\n        return rebasingCredits_ / RESOLUTION_INCREASE;\n    }\n\n    /**\n     * @notice 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        RebaseOptions state = rebaseState[_account];\n        if (state == RebaseOptions.YieldDelegationSource) {\n            // Saves a slot read when transferring to or from a yield delegating source\n            // since we know creditBalances equals the balance.\n            return creditBalances[_account];\n        }\n        uint256 baseBalance = (creditBalances[_account] * 1e18) /\n            _creditsPerToken(_account);\n        if (state == RebaseOptions.YieldDelegationTarget) {\n            // creditBalances of yieldFrom accounts equals token balances\n            return baseBalance - creditBalances[yieldFrom[_account]];\n        }\n        return baseBalance;\n    }\n\n    /**\n     * @notice Gets the credits balance of the specified address.\n     * @dev Backwards compatible with old low res credits per token.\n     * @param _account The address to query the balance of.\n     * @return (uint256, uint256) Credit balance and credits per token of the\n     *         address\n     */\n    function creditsBalanceOf(address _account)\n        external\n        view\n        returns (uint256, uint256)\n    {\n        uint256 cpt = _creditsPerToken(_account);\n        if (cpt == 1e27) {\n            // For a period before the resolution upgrade, we created all new\n            // contract accounts at high resolution. Since they are not changing\n            // as a result of this upgrade, we will return their true values\n            return (creditBalances[_account], cpt);\n        } else {\n            return (\n                creditBalances[_account] / RESOLUTION_INCREASE,\n                cpt / RESOLUTION_INCREASE\n            );\n        }\n    }\n\n    /**\n     * @notice Gets the credits balance of the specified address.\n     * @param _account The address to query the balance of.\n     * @return (uint256, uint256, bool) Credit balance, credits per token of the\n     *         address, and isUpgraded\n     */\n    function creditsBalanceOfHighres(address _account)\n        external\n        view\n        returns (\n            uint256,\n            uint256,\n            bool\n        )\n    {\n        return (\n            creditBalances[_account],\n            _creditsPerToken(_account),\n            true // all accounts have their resolution \"upgraded\"\n        );\n    }\n\n    // Backwards compatible view\n    function nonRebasingCreditsPerToken(address _account)\n        external\n        view\n        returns (uint256)\n    {\n        return alternativeCreditsPerToken[_account];\n    }\n\n    /**\n     * @notice 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) external returns (bool) {\n        require(_to != address(0), \"Transfer to zero address\");\n\n        _executeTransfer(msg.sender, _to, _value);\n\n        emit Transfer(msg.sender, _to, _value);\n        return true;\n    }\n\n    /**\n     * @notice 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     * @return true on success.\n     */\n    function transferFrom(\n        address _from,\n        address _to,\n        uint256 _value\n    ) external returns (bool) {\n        require(_to != address(0), \"Transfer to zero address\");\n        uint256 userAllowance = allowances[_from][msg.sender];\n        require(_value <= userAllowance, \"Allowance exceeded\");\n\n        unchecked {\n            allowances[_from][msg.sender] = userAllowance - _value;\n        }\n\n        _executeTransfer(_from, _to, _value);\n\n        emit Transfer(_from, _to, _value);\n        return true;\n    }\n\n    function _executeTransfer(\n        address _from,\n        address _to,\n        uint256 _value\n    ) internal {\n        (\n            int256 fromRebasingCreditsDiff,\n            int256 fromNonRebasingSupplyDiff\n        ) = _adjustAccount(_from, -_value.toInt256());\n        (\n            int256 toRebasingCreditsDiff,\n            int256 toNonRebasingSupplyDiff\n        ) = _adjustAccount(_to, _value.toInt256());\n\n        _adjustGlobals(\n            fromRebasingCreditsDiff + toRebasingCreditsDiff,\n            fromNonRebasingSupplyDiff + toNonRebasingSupplyDiff\n        );\n    }\n\n    function _adjustAccount(address _account, int256 _balanceChange)\n        internal\n        returns (int256 rebasingCreditsDiff, int256 nonRebasingSupplyDiff)\n    {\n        RebaseOptions state = rebaseState[_account];\n        int256 currentBalance = balanceOf(_account).toInt256();\n        if (currentBalance + _balanceChange < 0) {\n            revert(\"Transfer amount exceeds balance\");\n        }\n        uint256 newBalance = (currentBalance + _balanceChange).toUint256();\n\n        if (state == RebaseOptions.YieldDelegationSource) {\n            address target = yieldTo[_account];\n            uint256 targetOldBalance = balanceOf(target);\n            uint256 targetNewCredits = _balanceToRebasingCredits(\n                targetOldBalance + newBalance\n            );\n            rebasingCreditsDiff =\n                targetNewCredits.toInt256() -\n                creditBalances[target].toInt256();\n\n            creditBalances[_account] = newBalance;\n            creditBalances[target] = targetNewCredits;\n        } else if (state == RebaseOptions.YieldDelegationTarget) {\n            uint256 newCredits = _balanceToRebasingCredits(\n                newBalance + creditBalances[yieldFrom[_account]]\n            );\n            rebasingCreditsDiff =\n                newCredits.toInt256() -\n                creditBalances[_account].toInt256();\n            creditBalances[_account] = newCredits;\n        } else {\n            _autoMigrate(_account);\n            uint256 alternativeCreditsPerTokenMem = alternativeCreditsPerToken[\n                _account\n            ];\n            if (alternativeCreditsPerTokenMem > 0) {\n                nonRebasingSupplyDiff = _balanceChange;\n                if (alternativeCreditsPerTokenMem != 1e18) {\n                    alternativeCreditsPerToken[_account] = 1e18;\n                }\n                creditBalances[_account] = newBalance;\n            } else {\n                uint256 newCredits = _balanceToRebasingCredits(newBalance);\n                rebasingCreditsDiff =\n                    newCredits.toInt256() -\n                    creditBalances[_account].toInt256();\n                creditBalances[_account] = newCredits;\n            }\n        }\n    }\n\n    function _adjustGlobals(\n        int256 _rebasingCreditsDiff,\n        int256 _nonRebasingSupplyDiff\n    ) internal {\n        if (_rebasingCreditsDiff != 0) {\n            rebasingCredits_ = (rebasingCredits_.toInt256() +\n                _rebasingCreditsDiff).toUint256();\n        }\n        if (_nonRebasingSupplyDiff != 0) {\n            nonRebasingSupply = (nonRebasingSupply.toInt256() +\n                _nonRebasingSupplyDiff).toUint256();\n        }\n    }\n\n    /**\n     * @notice Function to check the amount of tokens that _owner has allowed\n     *      to `_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        external\n        view\n        returns (uint256)\n    {\n        return allowances[_owner][_spender];\n    }\n\n    /**\n     * @notice Approve the passed address to spend the specified amount of\n     *      tokens on behalf of msg.sender.\n     * @param _spender The address which will spend the funds.\n     * @param _value The amount of tokens to be spent.\n     * @return true on success.\n     */\n    function approve(address _spender, uint256 _value) external returns (bool) {\n        allowances[msg.sender][_spender] = _value;\n        emit Approval(msg.sender, _spender, _value);\n        return true;\n    }\n\n    /**\n     * @notice Creates `_amount` tokens and assigns them to `_account`,\n     *     increasing the total supply.\n     */\n    function mint(address _account, uint256 _amount) external onlyVault {\n        require(_account != address(0), \"Mint to the zero address\");\n\n        // Account\n        (\n            int256 toRebasingCreditsDiff,\n            int256 toNonRebasingSupplyDiff\n        ) = _adjustAccount(_account, _amount.toInt256());\n        // Globals\n        _adjustGlobals(toRebasingCreditsDiff, toNonRebasingSupplyDiff);\n        totalSupply = totalSupply + _amount;\n\n        require(totalSupply < MAX_SUPPLY, \"Max supply\");\n        emit Transfer(address(0), _account, _amount);\n    }\n\n    /**\n     * @notice Destroys `_amount` tokens from `_account`,\n     *     reducing the total supply.\n     */\n    function burn(address _account, uint256 _amount) external onlyVault {\n        require(_account != address(0), \"Burn from the zero address\");\n        if (_amount == 0) {\n            return;\n        }\n\n        // Account\n        (\n            int256 toRebasingCreditsDiff,\n            int256 toNonRebasingSupplyDiff\n        ) = _adjustAccount(_account, -_amount.toInt256());\n        // Globals\n        _adjustGlobals(toRebasingCreditsDiff, toNonRebasingSupplyDiff);\n        totalSupply = totalSupply - _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        uint256 alternativeCreditsPerTokenMem = alternativeCreditsPerToken[\n            _account\n        ];\n        if (alternativeCreditsPerTokenMem != 0) {\n            return alternativeCreditsPerTokenMem;\n        } else {\n            return rebasingCreditsPerToken_;\n        }\n    }\n\n    /**\n     * @dev Auto migrate contracts to be non rebasing,\n     *     unless they have opted into yield.\n     * @param _account Address of the account.\n     */\n    function _autoMigrate(address _account) internal {\n        uint256 codeLen = _account.code.length;\n        bool isEOA = (codeLen == 0) ||\n            (codeLen == 23 && bytes3(_account.code) == 0xef0100);\n        // In previous code versions, contracts would not have had their\n        // rebaseState[_account] set to RebaseOptions.NonRebasing when migrated\n        // therefore we check the actual accounting used on the account as well.\n        if (\n            (!isEOA) &&\n            rebaseState[_account] == RebaseOptions.NotSet &&\n            alternativeCreditsPerToken[_account] == 0\n        ) {\n            _rebaseOptOut(_account);\n        }\n    }\n\n    /**\n     * @dev Calculates credits from contract's global rebasingCreditsPerToken_, and\n     *      also balance that corresponds to those credits. The latter is important\n     *      when adjusting the contract's global nonRebasingSupply to circumvent any\n     *      possible rounding errors.\n     *\n     * @param _balance Balance of the account.\n     */\n    function _balanceToRebasingCredits(uint256 _balance)\n        internal\n        view\n        returns (uint256 rebasingCredits)\n    {\n        // Rounds up, because we need to ensure that accounts always have\n        // at least the balance that they should have.\n        // Note this should always be used on an absolute account value,\n        // not on a possibly negative diff, because then the rounding would be wrong.\n        return ((_balance) * rebasingCreditsPerToken_ + 1e18 - 1) / 1e18;\n    }\n\n    /**\n     * @notice The calling account will start receiving yield after a successful call.\n     * @param _account Address of the account.\n     */\n    function governanceRebaseOptIn(address _account) external onlyGovernor {\n        require(_account != address(0), \"Zero address not allowed\");\n        _rebaseOptIn(_account);\n    }\n\n    /**\n     * @notice The calling account will start receiving yield after a successful call.\n     */\n    function rebaseOptIn() external {\n        _rebaseOptIn(msg.sender);\n    }\n\n    function _rebaseOptIn(address _account) internal {\n        uint256 balance = balanceOf(_account);\n\n        // prettier-ignore\n        require(\n            alternativeCreditsPerToken[_account] > 0 ||\n                // Accounts may explicitly `rebaseOptIn` regardless of\n                // accounting if they have a 0 balance.\n                creditBalances[_account] == 0\n            ,\n            \"Account must be non-rebasing\"\n        );\n        RebaseOptions state = rebaseState[_account];\n        // prettier-ignore\n        require(\n            state == RebaseOptions.StdNonRebasing ||\n                state == RebaseOptions.NotSet,\n            \"Only standard non-rebasing accounts can opt in\"\n        );\n\n        uint256 newCredits = _balanceToRebasingCredits(balance);\n\n        // Account\n        rebaseState[_account] = RebaseOptions.StdRebasing;\n        alternativeCreditsPerToken[_account] = 0;\n        creditBalances[_account] = newCredits;\n        // Globals\n        _adjustGlobals(newCredits.toInt256(), -balance.toInt256());\n\n        emit AccountRebasingEnabled(_account);\n    }\n\n    /**\n     * @notice The calling account will no longer receive yield\n     */\n    function rebaseOptOut() external {\n        _rebaseOptOut(msg.sender);\n    }\n\n    function _rebaseOptOut(address _account) internal {\n        require(\n            alternativeCreditsPerToken[_account] == 0,\n            \"Account must be rebasing\"\n        );\n        RebaseOptions state = rebaseState[_account];\n        require(\n            state == RebaseOptions.StdRebasing || state == RebaseOptions.NotSet,\n            \"Only standard rebasing accounts can opt out\"\n        );\n\n        uint256 oldCredits = creditBalances[_account];\n        uint256 balance = balanceOf(_account);\n\n        // Account\n        rebaseState[_account] = RebaseOptions.StdNonRebasing;\n        alternativeCreditsPerToken[_account] = 1e18;\n        creditBalances[_account] = balance;\n        // Globals\n        _adjustGlobals(-oldCredits.toInt256(), balance.toInt256());\n\n        emit AccountRebasingDisabled(_account);\n    }\n\n    /**\n     * @notice Distribute yield to users. This changes the exchange rate\n     *  between \"credits\" and OUSD tokens to change rebasing user's balances.\n     * @param _newTotalSupply New total supply of OUSD.\n     */\n    function changeSupply(uint256 _newTotalSupply) external onlyVault {\n        require(totalSupply > 0, \"Cannot increase 0 supply\");\n\n        if (totalSupply == _newTotalSupply) {\n            emit TotalSupplyUpdatedHighres(\n                totalSupply,\n                rebasingCredits_,\n                rebasingCreditsPerToken_\n            );\n            return;\n        }\n\n        totalSupply = _newTotalSupply > MAX_SUPPLY\n            ? MAX_SUPPLY\n            : _newTotalSupply;\n\n        uint256 rebasingSupply = totalSupply - nonRebasingSupply;\n        // round up in the favour of the protocol\n        rebasingCreditsPerToken_ =\n            (rebasingCredits_ * 1e18 + rebasingSupply - 1) /\n            rebasingSupply;\n\n        require(rebasingCreditsPerToken_ > 0, \"Invalid change in supply\");\n\n        emit TotalSupplyUpdatedHighres(\n            totalSupply,\n            rebasingCredits_,\n            rebasingCreditsPerToken_\n        );\n    }\n\n    /*\n     * @notice Send the yield from one account to another account.\n     *         Each account keeps its own balances.\n     */\n    function delegateYield(address _from, address _to)\n        external\n        onlyGovernorOrStrategist\n    {\n        require(_from != address(0), \"Zero from address not allowed\");\n        require(_to != address(0), \"Zero to address not allowed\");\n\n        require(_from != _to, \"Cannot delegate to self\");\n        require(\n            yieldFrom[_to] == address(0) &&\n                yieldTo[_to] == address(0) &&\n                yieldFrom[_from] == address(0) &&\n                yieldTo[_from] == address(0),\n            \"Blocked by existing yield delegation\"\n        );\n        RebaseOptions stateFrom = rebaseState[_from];\n        RebaseOptions stateTo = rebaseState[_to];\n\n        require(\n            stateFrom == RebaseOptions.NotSet ||\n                stateFrom == RebaseOptions.StdNonRebasing ||\n                stateFrom == RebaseOptions.StdRebasing,\n            \"Invalid rebaseState from\"\n        );\n\n        require(\n            stateTo == RebaseOptions.NotSet ||\n                stateTo == RebaseOptions.StdNonRebasing ||\n                stateTo == RebaseOptions.StdRebasing,\n            \"Invalid rebaseState to\"\n        );\n\n        if (alternativeCreditsPerToken[_from] == 0) {\n            _rebaseOptOut(_from);\n        }\n        if (alternativeCreditsPerToken[_to] > 0) {\n            _rebaseOptIn(_to);\n        }\n\n        uint256 fromBalance = balanceOf(_from);\n        uint256 toBalance = balanceOf(_to);\n        uint256 oldToCredits = creditBalances[_to];\n        uint256 newToCredits = _balanceToRebasingCredits(\n            fromBalance + toBalance\n        );\n\n        // Set up the bidirectional links\n        yieldTo[_from] = _to;\n        yieldFrom[_to] = _from;\n\n        // Local\n        rebaseState[_from] = RebaseOptions.YieldDelegationSource;\n        alternativeCreditsPerToken[_from] = 1e18;\n        creditBalances[_from] = fromBalance;\n        rebaseState[_to] = RebaseOptions.YieldDelegationTarget;\n        creditBalances[_to] = newToCredits;\n\n        // Global\n        int256 creditsChange = newToCredits.toInt256() -\n            oldToCredits.toInt256();\n        _adjustGlobals(creditsChange, -(fromBalance).toInt256());\n        emit YieldDelegated(_from, _to);\n    }\n\n    /*\n     * @notice Stop sending the yield from one account to another account.\n     */\n    function undelegateYield(address _from) external onlyGovernorOrStrategist {\n        // Require a delegation, which will also ensure a valid delegation\n        require(yieldTo[_from] != address(0), \"Zero address not allowed\");\n\n        address to = yieldTo[_from];\n        uint256 fromBalance = balanceOf(_from);\n        uint256 toBalance = balanceOf(to);\n        uint256 oldToCredits = creditBalances[to];\n        uint256 newToCredits = _balanceToRebasingCredits(toBalance);\n\n        // Remove the bidirectional links\n        yieldFrom[to] = address(0);\n        yieldTo[_from] = address(0);\n\n        // Local\n        rebaseState[_from] = RebaseOptions.StdNonRebasing;\n        // alternativeCreditsPerToken[from] already 1e18 from `delegateYield()`\n        creditBalances[_from] = fromBalance;\n        rebaseState[to] = RebaseOptions.StdRebasing;\n        // alternativeCreditsPerToken[to] already 0 from `delegateYield()`\n        creditBalances[to] = newToCredits;\n\n        // Global\n        int256 creditsChange = newToCredits.toInt256() -\n            oldToCredits.toInt256();\n        _adjustGlobals(creditsChange, fromBalance.toInt256());\n        emit YieldUndelegated(_from, to);\n    }\n}\n"},{"file_path":"contracts/utils/Helpers.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport { IBasicToken } from \"../interfaces/IBasicToken.sol\";\n\nlibrary Helpers {\n    /**\n     * @notice Fetch the `symbol()` from an ERC20 token\n     * @dev Grabs the `symbol()` from a contract\n     * @param _token Address of the ERC20 token\n     * @return string Symbol of the ERC20 token\n     */\n    function getSymbol(address _token) internal view returns (string memory) {\n        string memory symbol = IBasicToken(_token).symbol();\n        return symbol;\n    }\n\n    /**\n     * @notice Fetch the `decimals()` from an ERC20 token\n     * @dev Grabs the `decimals()` from a contract and fails if\n     *      the decimal value does not live within a certain range\n     * @param _token Address of the ERC20 token\n     * @return uint256 Decimals of the ERC20 token\n     */\n    function getDecimals(address _token) internal view returns (uint256) {\n        uint256 decimals = IBasicToken(_token).decimals();\n        require(\n            decimals >= 4 && decimals <= 18,\n            \"Token must have sufficient decimal places\"\n        );\n\n        return decimals;\n    }\n}\n"},{"file_path":"contracts/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title Base contract any contracts that need to initialize state after deployment.\n * @author Origin Protocol Inc\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     */\n    bool private initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private initializing;\n\n    /**\n     * @dev Modifier to protect an initializer function from being invoked twice.\n     */\n    modifier initializer() {\n        require(\n            initializing || !initialized,\n            \"Initializable: contract is already initialized\"\n        );\n\n        bool isTopLevelCall = !initializing;\n        if (isTopLevelCall) {\n            initializing = true;\n            initialized = true;\n        }\n\n        _;\n\n        if (isTopLevelCall) {\n            initializing = false;\n        }\n    }\n\n    uint256[50] private ______gap;\n}\n"},{"file_path":"contracts/utils/StableMath.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport { SafeMath } from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\n\n// Based on StableMath from Stability Labs Pty. Ltd.\n// https://github.com/mstable/mStable-contracts/blob/master/contracts/shared/StableMath.sol\n\nlibrary StableMath {\n    using SafeMath for uint256;\n\n    /**\n     * @dev Scaling unit for use in specific calculations,\n     * where 1 * 10**18, or 1e18 represents a unit '1'\n     */\n    uint256 private constant FULL_SCALE = 1e18;\n\n    /***************************************\n                    Helpers\n    ****************************************/\n\n    /**\n     * @dev Adjust the scale of an integer\n     * @param to Decimals to scale to\n     * @param from Decimals to scale from\n     */\n    function scaleBy(\n        uint256 x,\n        uint256 to,\n        uint256 from\n    ) internal pure returns (uint256) {\n        if (to > from) {\n            x = x.mul(10**(to - from));\n        } else if (to < from) {\n            // slither-disable-next-line divide-before-multiply\n            x = x.div(10**(from - to));\n        }\n        return x;\n    }\n\n    /***************************************\n               Precise Arithmetic\n    ****************************************/\n\n    /**\n     * @dev Multiplies two precise units, and then truncates by the full scale\n     * @param x Left hand input to multiplication\n     * @param y Right hand input to multiplication\n     * @return Result after multiplying the two inputs and then dividing by the shared\n     *         scale unit\n     */\n    function mulTruncate(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulTruncateScale(x, y, FULL_SCALE);\n    }\n\n    /**\n     * @dev Multiplies two precise units, and then truncates by the given scale. For example,\n     * when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18\n     * @param x Left hand input to multiplication\n     * @param y Right hand input to multiplication\n     * @param scale Scale unit\n     * @return Result after multiplying the two inputs and then dividing by the shared\n     *         scale unit\n     */\n    function mulTruncateScale(\n        uint256 x,\n        uint256 y,\n        uint256 scale\n    ) internal pure returns (uint256) {\n        // e.g. assume scale = fullScale\n        // z = 10e18 * 9e17 = 9e36\n        uint256 z = x.mul(y);\n        // return 9e36 / 1e18 = 9e18\n        return z.div(scale);\n    }\n\n    /**\n     * @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result\n     * @param x Left hand input to multiplication\n     * @param y Right hand input to multiplication\n     * @return Result after multiplying the two inputs and then dividing by the shared\n     *          scale unit, rounded up to the closest base unit.\n     */\n    function mulTruncateCeil(uint256 x, uint256 y)\n        internal\n        pure\n        returns (uint256)\n    {\n        // e.g. 8e17 * 17268172638 = 138145381104e17\n        uint256 scaled = x.mul(y);\n        // e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17\n        uint256 ceil = scaled.add(FULL_SCALE.sub(1));\n        // e.g. 13814538111.399...e18 / 1e18 = 13814538111\n        return ceil.div(FULL_SCALE);\n    }\n\n    /**\n     * @dev Precisely divides two units, by first scaling the left hand operand. Useful\n     *      for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)\n     * @param x Left hand input to division\n     * @param y Right hand input to division\n     * @return Result after multiplying the left operand by the scale, and\n     *         executing the division on the right hand input.\n     */\n    function divPrecisely(uint256 x, uint256 y)\n        internal\n        pure\n        returns (uint256)\n    {\n        // e.g. 8e18 * 1e18 = 8e36\n        uint256 z = x.mul(FULL_SCALE);\n        // e.g. 8e36 / 10e18 = 8e17\n        return z.div(y);\n    }\n}\n"},{"file_path":"contracts/vault/VaultAdmin.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title OToken VaultAdmin contract\n * @notice The VaultAdmin contract makes configuration and admin calls on the vault.\n * @author Origin Protocol Inc\n */\n\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport { IVault } from \"../interfaces/IVault.sol\";\nimport { StableMath } from \"../utils/StableMath.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport \"./VaultCore.sol\";\n\nabstract contract VaultAdmin is VaultCore {\n    using SafeERC20 for IERC20;\n    using StableMath for uint256;\n    using SafeCast for uint256;\n\n    /**\n     * @dev Verifies that the caller is the Governor or Strategist.\n     */\n    modifier onlyGovernorOrStrategist() {\n        require(\n            msg.sender == strategistAddr || isGovernor(),\n            \"Caller is not the Strategist or Governor\"\n        );\n        _;\n    }\n\n    constructor(address _asset) VaultCore(_asset) {}\n\n    /***************************************\n                 Configuration\n    ****************************************/\n    /**\n     * @notice Set a buffer of asset to keep in the Vault to handle most\n     * redemptions without needing to spend gas unwinding asset from a Strategy.\n     * @param _vaultBuffer Percentage using 18 decimals. 100% = 1e18.\n     */\n    function setVaultBuffer(uint256 _vaultBuffer)\n        external\n        onlyGovernorOrStrategist\n    {\n        require(_vaultBuffer <= 1e18, \"Invalid value\");\n        vaultBuffer = _vaultBuffer;\n        emit VaultBufferUpdated(_vaultBuffer);\n    }\n\n    /**\n     * @notice Sets the minimum amount of OTokens in a mint to trigger an\n     * automatic allocation of funds afterwords.\n     * @param _threshold OToken amount with 18 fixed decimals.\n     */\n    function setAutoAllocateThreshold(uint256 _threshold)\n        external\n        onlyGovernor\n    {\n        autoAllocateThreshold = _threshold;\n        emit AllocateThresholdUpdated(_threshold);\n    }\n\n    /**\n     * @notice Set address of Strategist\n     * @param _address Address of Strategist\n     */\n    function setStrategistAddr(address _address) external onlyGovernor {\n        strategistAddr = _address;\n        emit StrategistUpdated(_address);\n    }\n\n    /**\n     * @notice Set the address authorized to call `rebase()`.\n     * @param _operator New operator address. May be set to the zero address\n     *                  to disable operator-initiated rebases.\n     */\n    function setOperatorAddr(address _operator) external onlyGovernor {\n        operatorAddr = _operator;\n        emit OperatorUpdated(_operator);\n    }\n\n    /**\n     * @notice Set the default Strategy for asset, i.e. the one which\n     * the asset will be automatically allocated to and withdrawn from\n     * @param _strategy Address of the Strategy\n     */\n    function setDefaultStrategy(address _strategy)\n        external\n        onlyGovernorOrStrategist\n    {\n        emit DefaultStrategyUpdated(_strategy);\n        // If its a zero address being passed for the strategy we are removing\n        // the default strategy\n        if (_strategy != address(0)) {\n            // Make sure the strategy meets some criteria\n            require(strategies[_strategy].isSupported, \"Strategy not approved\");\n            require(\n                IStrategy(_strategy).supportsAsset(asset),\n                \"Asset not supported by Strategy\"\n            );\n        }\n        defaultStrategy = _strategy;\n    }\n\n    /**\n     * @notice Changes the async withdrawal claim period for OETH & superOETHb\n     * @param _delay Delay period (should be between 10 mins to 7 days).\n     *          Set to 0 to disable async withdrawals\n     */\n    function setWithdrawalClaimDelay(uint256 _delay) external onlyGovernor {\n        require(\n            _delay == 0 || (_delay >= 10 minutes && _delay <= 15 days),\n            \"Invalid claim delay period\"\n        );\n        withdrawalClaimDelay = _delay;\n        emit WithdrawalClaimDelayUpdated(_delay);\n    }\n\n    // slither-disable-start reentrancy-no-eth\n    /**\n     * @notice Set a yield streaming max rate. This spreads yield over\n     * time if it is above the max rate. This is a per rebase APR which\n     * due to compounding differs from the yearly APR. Governance should\n     * consider this fact when picking a desired APR\n     * @param apr in 1e18 notation. 3 * 1e18 = 3% APR\n     */\n    function setRebaseRateMax(uint256 apr) external onlyGovernorOrStrategist {\n        // The old yield will be at the old rate\n        _rebase();\n        // Change the rate\n        uint256 newPerSecond = apr / 100 / 365 days;\n        require(newPerSecond <= MAX_REBASE_PER_SECOND, \"Rate too high\");\n        rebasePerSecondMax = newPerSecond.toUint64();\n        emit RebasePerSecondMaxChanged(newPerSecond);\n    }\n\n    // slither-disable-end reentrancy-no-eth\n\n    // slither-disable-start reentrancy-no-eth\n    /**\n     * @notice Set the drip duration period\n     * @param _dripDuration Time in seconds to target a constant yield rate\n     */\n    function setDripDuration(uint256 _dripDuration)\n        external\n        onlyGovernorOrStrategist\n    {\n        // The old yield will be at the old rate\n        _rebase();\n        dripDuration = _dripDuration.toUint64();\n        emit DripDurationChanged(_dripDuration);\n    }\n\n    // slither-disable-end reentrancy-no-eth\n\n    /***************************************\n                Strategy Config\n    ****************************************/\n\n    /**\n     * @notice Add a strategy to the Vault.\n     * @param _addr Address of the strategy to add\n     */\n    function approveStrategy(address _addr) external onlyGovernor {\n        require(!strategies[_addr].isSupported, \"Strategy already approved\");\n        require(\n            IStrategy(_addr).supportsAsset(asset),\n            \"Asset not supported by Strategy\"\n        );\n        strategies[_addr] = Strategy({ isSupported: true, _deprecated: 0 });\n        allStrategies.push(_addr);\n        emit StrategyApproved(_addr);\n    }\n\n    /**\n     * @notice Remove a strategy from the Vault.\n     * @param _addr Address of the strategy to remove\n     */\n\n    function removeStrategy(address _addr) external onlyGovernor {\n        require(strategies[_addr].isSupported, \"Strategy not approved\");\n        require(defaultStrategy != _addr, \"Strategy is default for asset\");\n\n        // Initialize strategyIndex with out of bounds result so function will\n        // revert if no valid index found\n        uint256 stratCount = allStrategies.length;\n        uint256 strategyIndex = stratCount;\n        for (uint256 i = 0; i < stratCount; ++i) {\n            if (allStrategies[i] == _addr) {\n                strategyIndex = i;\n                break;\n            }\n        }\n\n        if (strategyIndex < stratCount) {\n            allStrategies[strategyIndex] = allStrategies[stratCount - 1];\n            allStrategies.pop();\n\n            // Withdraw all assets BEFORE marking as unsupported so that AMO\n            // strategies can call burnForStrategy/mintForStrategy during withdrawAll\n            IStrategy strategy = IStrategy(_addr);\n            // slither-disable-next-line reentrancy-no-eth\n            strategy.withdrawAll();\n\n            // Mark the strategy as not supported\n            strategies[_addr].isSupported = false;\n            isMintWhitelistedStrategy[_addr] = false;\n\n            // 1e13 for 18 decimals. And 1e1(10) for 6 decimals\n            uint256 maxDustBalance = uint256(1e13).scaleBy(assetDecimals, 18);\n\n            /*\n             * Some strategies are not able to withdraw all of their funds in a synchronous call.\n             * Prevent the possible accidental removal of such strategies before their funds are withdrawn.\n             */\n            require(\n                strategy.checkBalance(asset) < maxDustBalance,\n                \"Strategy has funds\"\n            );\n            emit StrategyRemoved(_addr);\n        }\n    }\n\n    /**\n     * @notice Adds a strategy to the mint whitelist.\n     *          Reverts if strategy isn't approved on Vault.\n     * @param strategyAddr Strategy address\n     */\n    function addStrategyToMintWhitelist(address strategyAddr)\n        external\n        onlyGovernor\n    {\n        require(strategies[strategyAddr].isSupported, \"Strategy not approved\");\n\n        require(\n            !isMintWhitelistedStrategy[strategyAddr],\n            \"Already whitelisted\"\n        );\n\n        isMintWhitelistedStrategy[strategyAddr] = true;\n\n        emit StrategyAddedToMintWhitelist(strategyAddr);\n    }\n\n    /**\n     * @notice Removes a strategy from the mint whitelist.\n     * @param strategyAddr Strategy address\n     */\n    function removeStrategyFromMintWhitelist(address strategyAddr)\n        external\n        onlyGovernor\n    {\n        // Intentionally skipping `strategies.isSupported` check since\n        // we may wanna remove an address even after removing the strategy\n\n        require(isMintWhitelistedStrategy[strategyAddr], \"Not whitelisted\");\n\n        isMintWhitelistedStrategy[strategyAddr] = false;\n\n        emit StrategyRemovedFromMintWhitelist(strategyAddr);\n    }\n\n    /***************************************\n                Strategies\n    ****************************************/\n\n    /**\n     * @notice Deposit multiple asset from the vault into the strategy.\n     * @param _strategyToAddress Address of the Strategy to deposit asset into.\n     * @param _assets Array of asset address that will be deposited into the strategy.\n     * @param _amounts Array of amounts of each corresponding asset to deposit.\n     */\n    function depositToStrategy(\n        address _strategyToAddress,\n        address[] calldata _assets,\n        uint256[] calldata _amounts\n    ) external onlyGovernorOrStrategist nonReentrant {\n        _depositToStrategy(_strategyToAddress, _assets, _amounts);\n    }\n\n    function _depositToStrategy(\n        address _strategyToAddress,\n        address[] calldata _assets,\n        uint256[] calldata _amounts\n    ) internal virtual {\n        require(\n            strategies[_strategyToAddress].isSupported,\n            \"Invalid to Strategy\"\n        );\n        require(\n            _assets.length == 1 && _amounts.length == 1 && _assets[0] == asset,\n            \"Only asset is supported\"\n        );\n\n        // Check the there is enough asset to transfer once the backing\n        // asset reserved for the withdrawal queue is accounted for\n        require(\n            _amounts[0] <= _assetAvailable(),\n            \"Not enough assets available\"\n        );\n\n        // Send required amount of funds to the strategy\n        IERC20(asset).safeTransfer(_strategyToAddress, _amounts[0]);\n\n        // Deposit all the funds that have been sent to the strategy\n        IStrategy(_strategyToAddress).depositAll();\n    }\n\n    /**\n     * @notice Withdraw multiple asset from the strategy to the vault.\n     * @param _strategyFromAddress Address of the Strategy to withdraw asset from.\n     * @param _assets Array of asset address that will be withdrawn from the strategy.\n     * @param _amounts Array of amounts of each corresponding asset to withdraw.\n     */\n    function withdrawFromStrategy(\n        address _strategyFromAddress,\n        address[] calldata _assets,\n        uint256[] calldata _amounts\n    ) external onlyGovernorOrStrategist nonReentrant {\n        _withdrawFromStrategy(\n            address(this),\n            _strategyFromAddress,\n            _assets,\n            _amounts\n        );\n    }\n\n    /**\n     * @param _recipient can either be a strategy or the Vault\n     */\n    function _withdrawFromStrategy(\n        address _recipient,\n        address _strategyFromAddress,\n        address[] calldata _assets,\n        uint256[] calldata _amounts\n    ) internal virtual {\n        require(\n            strategies[_strategyFromAddress].isSupported,\n            \"Invalid from Strategy\"\n        );\n        require(_assets.length == _amounts.length, \"Parameter length mismatch\");\n\n        uint256 assetCount = _assets.length;\n        for (uint256 i = 0; i < assetCount; ++i) {\n            // Withdraw from Strategy to the recipient\n            IStrategy(_strategyFromAddress).withdraw(\n                _recipient,\n                _assets[i],\n                _amounts[i]\n            );\n        }\n\n        _addWithdrawalQueueLiquidity();\n    }\n\n    /**\n     * @notice Sets the maximum allowable difference between\n     * total supply and asset' value.\n     */\n    function setMaxSupplyDiff(uint256 _maxSupplyDiff) external onlyGovernor {\n        maxSupplyDiff = _maxSupplyDiff;\n        emit MaxSupplyDiffChanged(_maxSupplyDiff);\n    }\n\n    /**\n     * @notice Sets the trusteeAddress that can receive a portion of yield.\n     *      Setting to the zero address disables this feature.\n     */\n    function setTrusteeAddress(address _address) external onlyGovernor {\n        trusteeAddress = _address;\n        emit TrusteeAddressChanged(_address);\n    }\n\n    /**\n     * @notice Sets the TrusteeFeeBps to the percentage of yield that should be\n     *      received in basis points.\n     */\n    function setTrusteeFeeBps(uint256 _basis) external onlyGovernor {\n        require(_basis <= 5000, \"basis cannot exceed 50%\");\n        trusteeFeeBps = _basis;\n        emit TrusteeFeeBpsChanged(_basis);\n    }\n\n    /***************************************\n                    Pause\n    ****************************************/\n\n    /**\n     * @notice Set the deposit paused flag to true to prevent rebasing.\n     */\n    function pauseRebase() external onlyGovernorOrStrategist {\n        rebasePaused = true;\n        emit RebasePaused();\n    }\n\n    /**\n     * @notice Set the deposit paused flag to true to allow rebasing.\n     */\n    function unpauseRebase() external onlyGovernorOrStrategist {\n        rebasePaused = false;\n        emit RebaseUnpaused();\n    }\n\n    /**\n     * @notice Set the deposit paused flag to true to prevent capital movement.\n     */\n    function pauseCapital() external onlyGovernorOrStrategist {\n        capitalPaused = true;\n        emit CapitalPaused();\n    }\n\n    /**\n     * @notice Set the deposit paused flag to false to enable capital movement.\n     */\n    function unpauseCapital() external onlyGovernorOrStrategist {\n        capitalPaused = false;\n        emit CapitalUnpaused();\n    }\n\n    /***************************************\n                    Utils\n    ****************************************/\n\n    /**\n     * @notice Transfer token to governor. Intended for recovering tokens stuck in\n     *      contract, i.e. mistaken sends.\n     * @param _asset Address for the asset\n     * @param _amount Amount of the asset to transfer\n     */\n    function transferToken(address _asset, uint256 _amount)\n        external\n        onlyGovernor\n    {\n        require(asset != _asset, \"Only unsupported asset\");\n        IERC20(_asset).safeTransfer(governor(), _amount);\n    }\n\n    /***************************************\n             Strategies Admin\n    ****************************************/\n\n    /**\n     * @notice Withdraws all asset from the strategy and sends asset to the Vault.\n     * @param _strategyAddr Strategy address.\n     */\n    function withdrawAllFromStrategy(address _strategyAddr)\n        external\n        onlyGovernorOrStrategist\n    {\n        _withdrawAllFromStrategy(_strategyAddr);\n    }\n\n    function _withdrawAllFromStrategy(address _strategyAddr) internal virtual {\n        require(\n            strategies[_strategyAddr].isSupported,\n            \"Strategy is not supported\"\n        );\n        IStrategy strategy = IStrategy(_strategyAddr);\n        strategy.withdrawAll();\n        _addWithdrawalQueueLiquidity();\n    }\n\n    /**\n     * @notice Withdraws all asset from all the strategies and sends asset to the Vault.\n     */\n    function withdrawAllFromStrategies() external onlyGovernorOrStrategist {\n        _withdrawAllFromStrategies();\n    }\n\n    function _withdrawAllFromStrategies() internal virtual {\n        uint256 stratCount = allStrategies.length;\n        for (uint256 i = 0; i < stratCount; ++i) {\n            IStrategy(allStrategies[i]).withdrawAll();\n        }\n        _addWithdrawalQueueLiquidity();\n    }\n}\n"},{"file_path":"contracts/vault/VaultCore.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title OToken VaultCore contract\n * @notice The Vault contract stores asset. On a deposit, OTokens will be minted\n           and sent to the depositor. On a withdrawal, OTokens will be burned and\n           asset will be sent to the withdrawer. The Vault accepts deposits of\n           interest from yield bearing strategies which will modify the supply\n           of OTokens.\n * @author Origin Protocol Inc\n */\n\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { StableMath } from \"../utils/StableMath.sol\";\n\nimport \"./VaultInitializer.sol\";\n\nabstract contract VaultCore is VaultInitializer {\n    using SafeERC20 for IERC20;\n    using StableMath for uint256;\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    constructor(address _asset) VaultInitializer(_asset) {}\n\n    ////////////////////////////////////////////////////\n    ///                 MINT / BURN                  ///\n    ////////////////////////////////////////////////////\n    /**\n     * @notice Deposit a supported asset and mint OTokens.\n     * @dev Deprecated: use `mint(uint256 _amount)` instead.\n     * @dev Deprecated: param _asset Address of the asset being deposited\n     * @param _amount Amount of the asset being deposited\n     * @dev Deprecated: param _minimumOusdAmount Minimum OTokens to mint\n     */\n    function mint(\n        address,\n        uint256 _amount,\n        uint256\n    ) external whenNotCapitalPaused nonReentrant {\n        _mint(_amount);\n    }\n\n    /**\n     * @notice Deposit a supported asset and mint OTokens.\n     * @param _amount Amount of the asset being deposited\n     */\n    function mint(uint256 _amount) external whenNotCapitalPaused nonReentrant {\n        _mint(_amount);\n    }\n\n    // slither-disable-start reentrancy-no-eth\n    /**\n     * @dev Deposit a supported asset and mint OTokens.\n     * @param _amount Amount of the asset being deposited\n     */\n    function _mint(uint256 _amount) internal virtual {\n        require(_amount > 0, \"Amount must be greater than 0\");\n\n        // Scale amount to 18 decimals\n        uint256 scaledAmount = _amount.scaleBy(18, assetDecimals);\n\n        emit Mint(msg.sender, scaledAmount);\n\n        // Mint oTokens\n        oToken.mint(msg.sender, scaledAmount);\n\n        IERC20(asset).safeTransferFrom(msg.sender, address(this), _amount);\n\n        // Give priority to the withdrawal queue for the new asset liquidity\n        _addWithdrawalQueueLiquidity();\n\n        // Auto-allocate if necessary\n        if (scaledAmount >= autoAllocateThreshold) {\n            _allocate();\n        }\n    }\n\n    // slither-disable-end reentrancy-no-eth\n\n    /**\n     * @notice Mint OTokens for an allowed Strategy\n     * @param _amount Amount of OToken to mint\n     *\n     * Notice: can't use `nonReentrant` modifier since the `mint` function can\n     * call `allocate`, and that can trigger an AMO strategy to call this function\n     * while the execution of the `mint` has not yet completed -> causing a `nonReentrant` collision.\n     *\n     * Also important to understand is that this is a limitation imposed by the test suite.\n     * Production / mainnet contracts should never be configured in a way where mint/redeem functions\n     * that are moving funds between the Vault and end user wallets can influence strategies\n     * utilizing this function.\n     */\n    function mintForStrategy(uint256 _amount)\n        external\n        virtual\n        whenNotCapitalPaused\n    {\n        require(\n            strategies[msg.sender].isSupported == true,\n            \"Unsupported strategy\"\n        );\n        require(\n            isMintWhitelistedStrategy[msg.sender] == true,\n            \"Not whitelisted strategy\"\n        );\n\n        emit Mint(msg.sender, _amount);\n        // Mint matching amount of OTokens\n        oToken.mint(msg.sender, _amount);\n    }\n\n    /**\n     * @notice Burn OTokens for an allowed Strategy\n     * @param _amount Amount of OToken to burn\n     *\n     * @dev Notice: can't use `nonReentrant` modifier since the `redeem` function could\n     * require withdrawal on an AMO strategy and that one can call `burnForStrategy`\n     * while the execution of the `redeem` has not yet completed -> causing a `nonReentrant` collision.\n     *\n     * Also important to understand is that this is a limitation imposed by the test suite.\n     * Production / mainnet contracts should never be configured in a way where mint/redeem functions\n     * that are moving funds between the Vault and end user wallets can influence strategies\n     * utilizing this function.\n     */\n    function burnForStrategy(uint256 _amount)\n        external\n        virtual\n        whenNotCapitalPaused\n    {\n        require(\n            strategies[msg.sender].isSupported == true,\n            \"Unsupported strategy\"\n        );\n        require(\n            isMintWhitelistedStrategy[msg.sender] == true,\n            \"Not whitelisted strategy\"\n        );\n\n        emit Redeem(msg.sender, _amount);\n\n        // Burn OTokens\n        oToken.burn(msg.sender, _amount);\n    }\n\n    ////////////////////////////////////////////////////\n    ///               ASYNC WITHDRAWALS              ///\n    ////////////////////////////////////////////////////\n    /**\n     * @notice Request an asynchronous withdrawal of asset in exchange for OToken.\n     * The OToken is burned on request and the asset is transferred to the withdrawer on claim.\n     * This request can be claimed once the withdrawal queue's `claimable` amount\n     * is greater than or equal this request's `queued` amount.\n     * There is a minimum of 10 minutes before a request can be claimed. After that, the request just needs\n     * enough asset liquidity in the Vault to satisfy all the outstanding requests to that point in the queue.\n     * OToken is converted to asset at 1:1.\n     * @param _amount Amount of OToken to burn.\n     * @return requestId Unique ID for the withdrawal request\n     * @return queued Cumulative total of all asset queued including already claimed requests.\n     */\n    function requestWithdrawal(uint256 _amount)\n        external\n        virtual\n        whenNotCapitalPaused\n        nonReentrant\n        returns (uint256 requestId, uint256 queued)\n    {\n        require(_amount > 0, \"Amount must be greater than 0\");\n        require(withdrawalClaimDelay > 0, \"Async withdrawals not enabled\");\n\n        // The check that the requester has enough OToken is done in to later burn call\n\n        requestId = withdrawalQueueMetadata.nextWithdrawalIndex;\n        queued =\n            withdrawalQueueMetadata.queued +\n            _amount.scaleBy(assetDecimals, 18);\n\n        // Store the next withdrawal request\n        withdrawalQueueMetadata.nextWithdrawalIndex = SafeCast.toUint128(\n            requestId + 1\n        );\n        // Store the updated queued amount which reserves asset in the withdrawal queue\n        // and reduces the vault's total asset\n        withdrawalQueueMetadata.queued = SafeCast.toUint128(queued);\n        // Store the user's withdrawal request\n        // `queued` is in asset decimals, while `amount` is in OToken decimals (18)\n        withdrawalRequests[requestId] = WithdrawalRequest({\n            withdrawer: msg.sender,\n            claimed: false,\n            timestamp: uint40(block.timestamp),\n            amount: SafeCast.toUint128(_amount),\n            queued: SafeCast.toUint128(queued)\n        });\n\n        // Burn the user's OToken\n        oToken.burn(msg.sender, _amount);\n\n        // Prevent withdrawal if the vault is solvent by more than the allowed percentage\n        _postRedeem();\n\n        emit WithdrawalRequested(msg.sender, requestId, _amount, queued);\n    }\n\n    // slither-disable-start reentrancy-no-eth\n    /**\n     * @notice Claim a previously requested withdrawal once it is claimable.\n     * This request can be claimed once the withdrawal queue's `claimable` amount\n     * is greater than or equal this request's `queued` amount and 10 minutes has passed.\n     * If the requests is not claimable, the transaction will revert with `Queue pending liquidity`.\n     * If the request is not older than 10 minutes, the transaction will revert with `Claim delay not met`.\n     * OToken is converted to asset at 1:1.\n     * @param _requestId Unique ID for the withdrawal request\n     * @return amount Amount of asset transferred to the withdrawer\n     */\n    function claimWithdrawal(uint256 _requestId)\n        external\n        virtual\n        whenNotCapitalPaused\n        nonReentrant\n        returns (uint256 amount)\n    {\n        // Try and get more liquidity if there is not enough available\n        if (\n            withdrawalRequests[_requestId].queued >\n            withdrawalQueueMetadata.claimable\n        ) {\n            // Add any asset to the withdrawal queue\n            // this needs to remain here as:\n            //  - Vault can be funded and `addWithdrawalQueueLiquidity` is not externally called\n            //  - funds can be withdrawn from a strategy\n            //\n            // Those funds need to be added to withdrawal queue liquidity\n            _addWithdrawalQueueLiquidity();\n        }\n\n        // Scale amount to asset decimals\n        amount = _claimWithdrawal(_requestId);\n\n        // transfer asset from the vault to the withdrawer\n        IERC20(asset).safeTransfer(msg.sender, amount);\n\n        // Prevent insolvency\n        _postRedeem();\n    }\n\n    // slither-disable-end reentrancy-no-eth\n    /**\n     * @notice Claim a previously requested withdrawals once they are claimable.\n     * This requests can be claimed once the withdrawal queue's `claimable` amount\n     * is greater than or equal each request's `queued` amount and 10 minutes has passed.\n     * If one of the requests is not claimable, the whole transaction will revert with `Queue pending liquidity`.\n     * If one of the requests is not older than 10 minutes,\n     * the whole transaction will revert with `Claim delay not met`.\n     * @param _requestIds Unique ID of each withdrawal request\n     * @return amounts Amount of asset received for each request\n     * @return totalAmount Total amount of asset transferred to the withdrawer\n     */\n    function claimWithdrawals(uint256[] calldata _requestIds)\n        external\n        virtual\n        whenNotCapitalPaused\n        nonReentrant\n        returns (uint256[] memory amounts, uint256 totalAmount)\n    {\n        // Add any asset to the withdrawal queue\n        // this needs to remain here as:\n        //  - Vault can be funded and `addWithdrawalQueueLiquidity` is not externally called\n        //  - funds can be withdrawn from a strategy\n        //\n        // Those funds need to be added to withdrawal queue liquidity\n        _addWithdrawalQueueLiquidity();\n\n        amounts = new uint256[](_requestIds.length);\n        for (uint256 i; i < _requestIds.length; ++i) {\n            // Scale all amounts to asset decimals, thus totalAmount is also in asset decimals\n            amounts[i] = _claimWithdrawal(_requestIds[i]);\n            totalAmount += amounts[i];\n        }\n\n        // transfer all the claimed asset from the vault to the withdrawer\n        IERC20(asset).safeTransfer(msg.sender, totalAmount);\n\n        // Prevent insolvency\n        _postRedeem();\n\n        return (amounts, totalAmount);\n    }\n\n    function _claimWithdrawal(uint256 requestId)\n        internal\n        returns (uint256 amount)\n    {\n        require(withdrawalClaimDelay > 0, \"Async withdrawals not enabled\");\n\n        // Load the structs from storage into memory\n        WithdrawalRequest memory request = withdrawalRequests[requestId];\n        WithdrawalQueueMetadata memory queue = withdrawalQueueMetadata;\n\n        require(\n            request.timestamp + withdrawalClaimDelay <= block.timestamp,\n            \"Claim delay not met\"\n        );\n        // If there isn't enough reserved liquidity in the queue to claim\n        require(request.queued <= queue.claimable, \"Queue pending liquidity\");\n        require(request.withdrawer == msg.sender, \"Not requester\");\n        require(request.claimed == false, \"Already claimed\");\n\n        // Store the request as claimed\n        withdrawalRequests[requestId].claimed = true;\n        // Store the updated claimed amount\n        withdrawalQueueMetadata.claimed =\n            queue.claimed +\n            SafeCast.toUint128(\n                StableMath.scaleBy(request.amount, assetDecimals, 18)\n            );\n\n        emit WithdrawalClaimed(msg.sender, requestId, request.amount);\n\n        return StableMath.scaleBy(request.amount, assetDecimals, 18);\n    }\n\n    function _postRedeem() internal view {\n        // Until we can prove that we won't affect the prices of our asset\n        // by withdrawing them, this should be here.\n        // It's possible that a strategy was off on its asset total, perhaps\n        // a reward token sold for more or for less than anticipated.\n        uint256 totalUnits = _totalValue();\n\n        // Check that the OTokens are backed by enough asset\n        if (maxSupplyDiff > 0) {\n            // If there are more outstanding withdrawal requests than asset in the vault and strategies\n            // then the available asset will be negative and totalUnits will be rounded up to zero.\n            // As we don't know the exact shortfall amount, we will reject all redeem and withdrawals\n            require(totalUnits > 0, \"Too many outstanding requests\");\n\n            // Allow a max difference of maxSupplyDiff% between\n            // asset value and OUSD total supply\n            uint256 diff = oToken.totalSupply().divPrecisely(totalUnits);\n            require(\n                (diff > 1e18 ? diff - 1e18 : 1e18 - diff) <= maxSupplyDiff,\n                \"Backing supply liquidity error\"\n            );\n        }\n    }\n\n    /**\n     * @notice Allocate unallocated funds on Vault to strategies.\n     */\n    function allocate() external virtual whenNotCapitalPaused nonReentrant {\n        // Add any unallocated asset to the withdrawal queue first\n        _addWithdrawalQueueLiquidity();\n\n        _allocate();\n    }\n\n    /**\n     * @dev Allocate asset (eg. WETH or USDC) to the default asset strategy\n     *          if there is excess to the Vault buffer.\n     * This is called from either `mint` or `allocate` and assumes `_addWithdrawalQueueLiquidity`\n     * has been called before this function.\n     */\n    function _allocate() internal virtual {\n        // No need to do anything if no default strategy for asset\n        address depositStrategyAddr = defaultStrategy;\n        if (depositStrategyAddr == address(0)) return;\n\n        uint256 assetAvailableInVault = _assetAvailable();\n        // No need to do anything if there isn't any asset in the vault to allocate\n        if (assetAvailableInVault == 0) return;\n\n        // Calculate the target buffer for the vault using the total supply\n        uint256 totalSupply = oToken.totalSupply();\n        // Scaled to asset decimals\n        uint256 targetBuffer = totalSupply.mulTruncate(vaultBuffer).scaleBy(\n            assetDecimals,\n            18\n        );\n\n        // If available asset in the Vault is below or equal the target buffer then there's nothing to allocate\n        if (assetAvailableInVault <= targetBuffer) return;\n\n        // The amount of asset to allocate to the default strategy\n        uint256 allocateAmount = assetAvailableInVault - targetBuffer;\n\n        IStrategy strategy = IStrategy(depositStrategyAddr);\n        // Transfer asset to the strategy and call the strategy's deposit function\n        IERC20(asset).safeTransfer(address(strategy), allocateAmount);\n        strategy.deposit(asset, allocateAmount);\n\n        emit AssetAllocated(asset, depositStrategyAddr, allocateAmount);\n    }\n\n    /**\n     * @notice Calculate the total value of asset held by the Vault and all\n     *      strategies and update the supply of OTokens.\n     * @dev Restricted to the Operator, Strategist or Governor.\n     */\n    function rebase() external virtual nonReentrant {\n        require(\n            msg.sender == operatorAddr ||\n                msg.sender == strategistAddr ||\n                isGovernor(),\n            \"Caller not authorized\"\n        );\n        _rebase();\n    }\n\n    /**\n     * @dev Calculate the total value of asset held by the Vault and all\n     *      strategies and update the supply of OTokens, optionally sending a\n     *      portion of the yield to the trustee.\n     * @return totalUnits Total balance of Vault in units\n     */\n    function _rebase() internal whenNotRebasePaused returns (uint256) {\n        uint256 supply = oToken.totalSupply();\n        uint256 vaultValue = _totalValue();\n        // If no supply yet, do not rebase\n        if (supply == 0) {\n            return vaultValue;\n        }\n\n        // Calculate yield and new supply\n        (uint256 yield, uint256 targetRate) = _nextYield(supply, vaultValue);\n        uint256 newSupply = supply + yield;\n        // Only rebase upwards and if we have enough backing funds\n        if (newSupply <= supply || newSupply > vaultValue) {\n            return vaultValue;\n        }\n\n        rebasePerSecondTarget = uint64(_min(targetRate, type(uint64).max));\n        lastRebase = uint64(block.timestamp); // Intentional cast\n\n        // Fee collection on yield\n        address _trusteeAddress = trusteeAddress; // gas savings\n        uint256 fee = 0;\n        if (_trusteeAddress != address(0)) {\n            fee = (yield * trusteeFeeBps) / 1e4;\n            if (fee > 0) {\n                require(fee < yield, \"Fee must not be greater than yield\");\n                oToken.mint(_trusteeAddress, fee);\n            }\n        }\n        emit YieldDistribution(_trusteeAddress, yield, fee);\n\n        // Only ratchet OToken supply upwards\n        // Final check uses latest totalSupply\n        if (newSupply > oToken.totalSupply()) {\n            oToken.changeSupply(newSupply);\n        }\n        return vaultValue;\n    }\n\n    /**\n     * @notice Calculates the amount that would rebase at next rebase.\n     * This is before any fees.\n     * @return yield amount of expected yield\n     */\n    function previewYield() external view returns (uint256 yield) {\n        (yield, ) = _nextYield(oToken.totalSupply(), _totalValue());\n        return yield;\n    }\n\n    /**\n     * @dev Calculates the amount that would rebase at next rebase.\n     *      See this Readme for detailed explanation:\n     *      contracts/contracts/vault/README - Yield Limits.md\n     */\n    function _nextYield(uint256 supply, uint256 vaultValue)\n        internal\n        view\n        virtual\n        returns (uint256 yield, uint256 targetRate)\n    {\n        uint256 nonRebasing = oToken.nonRebasingSupply();\n        uint256 rebasing = supply - nonRebasing;\n        uint256 elapsed = block.timestamp - lastRebase;\n        targetRate = rebasePerSecondTarget;\n\n        if (\n            elapsed == 0 || // Yield only once per block.\n            rebasing == 0 || // No yield if there are no rebasing tokens to give it to.\n            supply > vaultValue || // No yield if we do not have yield to give.\n            block.timestamp >= type(uint64).max // No yield if we are too far in the future to calculate it correctly.\n        ) {\n            return (0, targetRate);\n        }\n\n        // Start with the full difference available\n        yield = vaultValue - supply;\n\n        // Cap via optional automatic duration smoothing\n        uint256 _dripDuration = dripDuration;\n        if (_dripDuration > 1) {\n            // If we are able to sustain an increased drip rate for\n            // double the duration, then increase the target drip rate\n            targetRate = _max(targetRate, yield / (_dripDuration * 2));\n            // If we cannot sustain the target rate any more,\n            // then rebase what we can, and reduce the target\n            targetRate = _min(targetRate, yield / _dripDuration);\n            // drip at the new target rate\n            yield = _min(yield, targetRate * elapsed);\n        }\n\n        // Cap per second. elapsed is not 1e18 denominated\n        yield = _min(yield, (rebasing * elapsed * rebasePerSecondMax) / 1e18);\n\n        // Cap at a hard max per rebase, to avoid long durations resulting in huge rebases\n        yield = _min(yield, (rebasing * MAX_REBASE) / 1e18);\n\n        return (yield, targetRate);\n    }\n\n    /**\n     * @notice Determine the total value of asset held by the vault and its\n     *         strategies.\n     * @return value Total value in USD/ETH (1e18)\n     */\n    function totalValue() external view virtual returns (uint256 value) {\n        value = _totalValue();\n    }\n\n    /**\n     * @dev Internal Calculate the total value of the asset held by the\n     *          vault and its strategies.\n     * @dev The total value of all WETH held by the vault and all its strategies\n     *          less any WETH that is reserved for the withdrawal queue.\n     *          If there is not enough WETH in the vault and all strategies to cover\n     *          all outstanding withdrawal requests then return a total value of 0.\n     * @return value Total value in USD/ETH (1e18)\n     */\n    function _totalValue() internal view virtual returns (uint256 value) {\n        // As asset is the only asset, just return the asset balance\n        value = _checkBalance(asset).scaleBy(18, assetDecimals);\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     * @dev Get the balance of an asset held in Vault and all strategies\n     * less any asset that is reserved for the withdrawal queue.\n     * BaseAsset is the only asset that can return a non-zero balance.\n     * All other asset will return 0 even if there is some dust amounts left in the Vault.\n     * For example, there is 1 wei left of stETH (or USDC) in the OETH (or OUSD) Vault but\n     * will return 0 in this function.\n     *\n     * If there is not enough asset in the vault and all strategies to cover all outstanding\n     * withdrawal requests then return a asset balance of 0\n     * @param _asset Address of asset\n     * @return balance Balance of asset in decimals of asset\n     */\n    function _checkBalance(address _asset)\n        internal\n        view\n        virtual\n        returns (uint256 balance)\n    {\n        if (_asset != asset) return 0;\n\n        // Get the asset in the vault and the strategies\n        IERC20 asset = IERC20(_asset);\n        balance = asset.balanceOf(address(this));\n        uint256 stratCount = allStrategies.length;\n        for (uint256 i = 0; i < stratCount; ++i) {\n            IStrategy strategy = IStrategy(allStrategies[i]);\n            if (strategy.supportsAsset(_asset)) {\n                balance = balance + strategy.checkBalance(_asset);\n            }\n        }\n\n        WithdrawalQueueMetadata memory queue = withdrawalQueueMetadata;\n\n        // If the vault becomes insolvent enough that the total value in the vault and all strategies\n        // is less than the outstanding withdrawals.\n        // For example, there was a mass slashing event and most users request a withdrawal.\n        if (balance + queue.claimed < queue.queued) {\n            return 0;\n        }\n\n        // Need to remove asset that is reserved for the withdrawal queue\n        return balance + queue.claimed - queue.queued;\n    }\n\n    /**\n     * @notice Adds WETH to the withdrawal queue if there is a funding shortfall.\n     * @dev is called from the Native Staking strategy when validator withdrawals are processed.\n     * It also called before any WETH is allocated to a strategy.\n     */\n    function addWithdrawalQueueLiquidity() external {\n        _addWithdrawalQueueLiquidity();\n    }\n\n    /**\n     * @dev Adds asset (eg. WETH or USDC) to the withdrawal queue if there is a funding shortfall.\n     * This assumes 1 asset equal 1 corresponding OToken.\n     */\n    function _addWithdrawalQueueLiquidity()\n        internal\n        returns (uint256 addedClaimable)\n    {\n        WithdrawalQueueMetadata memory queue = withdrawalQueueMetadata;\n\n        // Check if the claimable asset is less than the queued amount\n        uint256 queueShortfall = queue.queued - queue.claimable;\n\n        // No need to do anything is the withdrawal queue is full funded\n        if (queueShortfall == 0) {\n            return 0;\n        }\n\n        uint256 assetBalance = IERC20(asset).balanceOf(address(this));\n\n        // Of the claimable withdrawal requests, how much is unclaimed?\n        // That is, the amount of asset that is currently allocated for the withdrawal queue\n        uint256 allocatedBaseAsset = queue.claimable - queue.claimed;\n\n        // If there is no unallocated asset then there is nothing to add to the queue\n        if (assetBalance <= allocatedBaseAsset) {\n            return 0;\n        }\n\n        uint256 unallocatedBaseAsset = assetBalance - allocatedBaseAsset;\n        // the new claimable amount is the smaller of the queue shortfall or unallocated asset\n        addedClaimable = queueShortfall < unallocatedBaseAsset\n            ? queueShortfall\n            : unallocatedBaseAsset;\n        uint256 newClaimable = queue.claimable + addedClaimable;\n\n        // Store the new claimable amount back to storage\n        withdrawalQueueMetadata.claimable = SafeCast.toUint128(newClaimable);\n\n        // emit a WithdrawalClaimable event\n        emit WithdrawalClaimable(newClaimable, addedClaimable);\n    }\n\n    /**\n     * @dev Calculate how much asset (eg. WETH or USDC) in the vault is not reserved for the withdrawal queue.\n     * That is, it is available to be redeemed or deposited into a strategy.\n     */\n    function _assetAvailable() internal view returns (uint256 assetAvailable) {\n        WithdrawalQueueMetadata memory queue = withdrawalQueueMetadata;\n\n        // The amount of asset that is still to be claimed in the withdrawal queue\n        uint256 outstandingWithdrawals = queue.queued - queue.claimed;\n\n        // The amount of sitting in asset in the vault\n        uint256 assetBalance = IERC20(asset).balanceOf(address(this));\n        // If there is not enough asset in the vault to cover the outstanding withdrawals\n        if (assetBalance <= outstandingWithdrawals) return 0;\n\n        return assetBalance - outstandingWithdrawals;\n    }\n\n    /***************************************\n                    Utils\n    ****************************************/\n\n    /**\n     * @notice Return the number of asset supported by the Vault.\n     */\n    function getAssetCount() public view returns (uint256) {\n        return 1;\n    }\n\n    /**\n     * @notice Return all vault asset addresses in order\n     */\n    function getAllAssets() external view returns (address[] memory) {\n        address[] memory a = new address[](1);\n        a[0] = asset;\n        return a;\n    }\n\n    /**\n     * @notice Return the number of strategies active on the Vault.\n     */\n    function getStrategyCount() external view returns (uint256) {\n        return allStrategies.length;\n    }\n\n    /**\n     * @notice Return the array of all strategies\n     */\n    function getAllStrategies() external view returns (address[] memory) {\n        return allStrategies;\n    }\n\n    /**\n     * @notice Returns whether the vault supports the asset\n     * @param _asset address of the asset\n     * @return true if supported\n     */\n    function isSupportedAsset(address _asset) external view returns (bool) {\n        return asset == _asset;\n    }\n\n    function _min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    function _max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_usdc","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"AllocateThresholdUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"AssetAllocated","type":"event"},{"anonymous":false,"inputs":[],"name":"CapitalPaused","type":"event"},{"anonymous":false,"inputs":[],"name":"CapitalUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_strategy","type":"address"}],"name":"DefaultStrategyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dripDuration","type":"uint256"}],"name":"DripDurationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"GovernorshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxSupplyDiff","type":"uint256"}],"name":"MaxSupplyDiffChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOperator","type":"address"}],"name":"OperatorUpdated","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":[],"name":"RebasePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rebaseRatePerSecond","type":"uint256"}],"name":"RebasePerSecondMaxChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"RebaseUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"StrategistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"StrategyAddedToMintWhitelist","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":true,"internalType":"address","name":"strategy","type":"address"}],"name":"StrategyRemovedFromMintWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"TrusteeAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_basis","type":"uint256"}],"name":"TrusteeFeeBpsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_vaultBuffer","type":"uint256"}],"name":"VaultBufferUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newDelay","type":"uint256"}],"name":"WithdrawalClaimDelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_claimable","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newClaimable","type":"uint256"}],"name":"WithdrawalClaimable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_withdrawer","type":"address"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"WithdrawalClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_withdrawer","type":"address"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_queued","type":"uint256"}],"name":"WithdrawalRequested","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"},{"inputs":[{"internalType":"address","name":"strategyAddr","type":"address"}],"name":"addStrategyToMintWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addWithdrawalQueueLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"approveStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoAllocateThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnForStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"capitalPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"checkBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"claimWithdrawal","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_requestIds","type":"uint256[]"}],"name":"claimWithdrawals","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultStrategy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyToAddress","type":"address"},{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"depositToStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dripDuration","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllAssets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStrategies","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStrategyCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMintWhitelistedStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"isSupportedAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRebase","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyDiff","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintForStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oToken","outputs":[{"internalType":"contract OUSD","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oUSD","outputs":[{"internalType":"contract OUSD","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseCapital","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseRebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"previewYield","outputs":[{"internalType":"uint256","name":"yield","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebasePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebasePerSecondMax","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebasePerSecondTarget","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"removeStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategyAddr","type":"address"}],"name":"removeStrategyFromMintWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"requestWithdrawal","outputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"queued","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setAutoAllocateThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"}],"name":"setDefaultStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dripDuration","type":"uint256"}],"name":"setDripDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupplyDiff","type":"uint256"}],"name":"setMaxSupplyDiff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperatorAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"apr","type":"uint256"}],"name":"setRebaseRateMax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setStrategistAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setTrusteeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_basis","type":"uint256"}],"name":"setTrusteeFeeBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultBuffer","type":"uint256"}],"name":"setVaultBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setWithdrawalClaimDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategies","outputs":[{"internalType":"bool","name":"isSupported","type":"bool"},{"internalType":"uint256","name":"_deprecated","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategistAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"trusteeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trusteeFeeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpauseCapital","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseRebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAllFromStrategies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyAddr","type":"address"}],"name":"withdrawAllFromStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyFromAddress","type":"address"},{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"withdrawFromStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalClaimDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalQueueMetadata","outputs":[{"internalType":"uint128","name":"queued","type":"uint128"},{"internalType":"uint128","name":"claimable","type":"uint128"},{"internalType":"uint128","name":"claimed","type":"uint128"},{"internalType":"uint128","name":"nextWithdrawalIndex","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalRequests","outputs":[{"internalType":"address","name":"withdrawer","type":"address"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"queued","type":"uint128"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"}