Source Code
Overview
MOVR Balance
MOVR Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Bank | 2912790 | 1179 days ago | IN | 0 MOVR | 0.00019841 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OhMultichainManager
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {OhManager} from "./OhManager.sol";
import {OhSubscriber} from "../registry/OhSubscriber.sol";
import {TransferHelper} from "../libraries/TransferHelper.sol";
import {ILiquidator} from "../interfaces/ILiquidator.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IMultichainManager} from "../interfaces/manager/IMultichainManager.sol";
contract OhMultichainManager is OhManager, IMultichainManager {
address public override burner;
/// @notice Deploy the Manager with the Registry reference
/// @dev Sets initial buyback and management fee parameters
/// @param registry_ The address of the registry
/// @param token_ The address of the Oh! Token
constructor(address registry_, address token_) OhManager(registry_, token_) {}
/// @notice Perform a token buyback with accrued revenue
/// @dev Burns all proceeds
/// @param from The address of the token to liquidate for Oh! Tokens
function buyback(address from) external override defense {
// get token, liquidator, and liquidation amount
address _token = token;
address liquidator = liquidators[from][_token];
uint256 amount = IERC20(from).balanceOf(address(this));
// send to liquidator, buyback and burn
TransferHelper.safeTokenTransfer(liquidator, from, amount);
uint256 received = ILiquidator(liquidator).liquidate(address(this), from, _token, amount, 1);
emit Buyback(from, amount, received);
}
function burn() external override defense {
require(burner != address(0), "Manager: No Burner");
uint256 amount = IERC20(token).balanceOf(address(this));
TransferHelper.safeTokenTransfer(burner, token, amount);
}
function setBurner(address _burner) external override onlyGovernance {
burner = _burner;
}
function setToken(address _token) external override onlyGovernance {
token = _token;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/EnumerableSet.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {IBank} from "../interfaces/bank/IBank.sol";
import {ILiquidator} from "../interfaces/ILiquidator.sol";
import {IManager} from "../interfaces/manager/IManager.sol";
import {IToken} from "../interfaces/IToken.sol";
import {TransferHelper} from "../libraries/TransferHelper.sol";
import {OhSubscriber} from "../registry/OhSubscriber.sol";
/// @title Oh! Finance Manager
/// @notice The Manager contains references to all active banks, strategies, and liquidation contracts.
/// @dev This contract is used as the main control point for executing strategies
contract OhManager is OhSubscriber, IManager {
using Address for address;
using EnumerableSet for EnumerableSet.AddressSet;
using SafeMath for uint256;
/// @notice Denominator for calculating protocol fees
uint256 public constant FEE_DENOMINATOR = 1000;
/// @notice Maximum buyback fee, 50%
uint256 public constant MAX_BUYBACK_FEE = 500;
/// @notice Minimum buyback fee, 10%
uint256 public constant MIN_BUYBACK_FEE = 100;
/// @notice Maximum management fee, 10%
uint256 public constant MAX_MANAGEMENT_FEE = 100;
/// @notice Minimum management fee, 0%
uint256 public constant MIN_MANAGEMENT_FEE = 0;
/// @notice The address of the Oh! Finance Token
address public override token;
/// @notice The amount of profits reserved for protocol buybacks, base 1000
uint256 public override buybackFee;
/// @notice The amount of profits reserved for fund management, base 1000
uint256 public override managementFee;
/// @notice The mapping of `from` token to `to` token to liquidator contract
mapping(address => mapping(address => address)) public override liquidators;
/// @notice The mapping of contracts that are whitelisted for Bank use/management
mapping(address => bool) public override whitelisted;
/// @dev The set of Banks approved for investing
EnumerableSet.AddressSet internal _banks;
/// @dev The mapping of Banks to active Strategies
mapping(address => EnumerableSet.AddressSet) internal _strategies;
/// @dev The mapping of Banks to next Strategy index it will deposit to
mapping(address => uint8) internal _depositQueue;
/// @dev The mapping of Banks to next Strategy index it will withdraw from
mapping(address => uint8) internal _withdrawQueue;
/// @notice Emitted when a Bank's capital is rebalanced
event Rebalance(address indexed bank);
/// @notice Emitted when a Bank's capital is invested in a single Strategy
event Finance(address indexed bank, address indexed strategy);
/// @notice Emitted when a Bank's capital is invested in all Strategies
event FinanceAll(address indexed bank);
/// @notice Emitted when a buyback is performed with an amount of from tokens
event Buyback(address indexed from, uint256 amount, uint256 buybackAmount);
/// @notice Emitted when a Bank realizes profit via liquidation
event AccrueRevenue(
address indexed bank,
address indexed strategy,
uint256 profitAmount,
uint256 buybackAmount,
uint256 managementAmount
);
/// @notice Only allow function calls if sender is an approved Bank
/// @param sender The address of the caller to validate
modifier onlyBank(address sender) {
require(_banks.contains(sender), "Manager: Only Bank");
_;
}
/// @notice Only allow function calls if sender is an approved Strategy
/// @param bank The address of the Bank that uses the Strategy
/// @param sender The address of the caller to validate
modifier onlyStrategy(address bank, address sender) {
require(_strategies[bank].contains(sender), "Manager: Only Strategy");
_;
}
/// @notice Only allow EOAs or Whitelisted contracts to interact
/// @dev Prevents sandwich / flash loan attacks & re-entrancy
modifier defense() {
require(msg.sender == tx.origin || whitelisted[msg.sender], "Manager: Only EOA or Whitelist");
_;
}
/// @notice Deploy the Manager with the Registry reference
/// @dev Sets initial buyback and management fee parameters
/// @param registry_ The address of the registry
/// @param token_ The address of the Oh! Token
constructor(address registry_, address token_) OhSubscriber(registry_) {
token = token_;
buybackFee = 200; // 20%
managementFee = 20; // 2%
}
/// @notice Get the Bank
function banks(uint256 i) external view override returns (address) {
return _banks.at(i);
}
function totalBanks() external view override returns (uint256) {
return _banks.length();
}
/// @notice Get the Strategy at a given index for a given Bank
/// @param bank The address of the Bank that contains the Strategy
/// @param i The Bank queue index to check
function strategies(address bank, uint256 i) external view override returns (address) {
return _strategies[bank].at(i);
}
/// @notice Get total number of strategies for a given bank
/// @param bank The Bank we are checking
/// @return Amount of active strategies
function totalStrategies(address bank) external view override returns (uint256) {
return _strategies[bank].length();
}
/// @notice Get the index of the Strategy to withdraw from for a given Bank
/// @param bank The Bank to check the next Strategy for
/// @return The index of the Strategy
function withdrawIndex(address bank) external view override returns (uint256) {
return _withdrawQueue[bank];
}
/// @notice Set the withdrawal index
/// @param i The index value
function setWithdrawIndex(uint256 i) external override onlyBank(msg.sender) {
_withdrawQueue[msg.sender] = uint8(i);
}
/// @notice Rebalance Bank exposure by withdrawing all, then evenly distributing underlying to all strategies
/// @param bank The bank to rebalance
function rebalance(address bank) external override defense onlyBank(bank) {
// Exit all strategies
uint256 length = _strategies[bank].length();
for (uint256 i; i < length; i++) {
IBank(bank).exitAll(_strategies[bank].at(i));
}
// Re-invest underlying evenly
uint256 toInvest = IBank(bank).underlyingBalance();
for (uint256 i; i < length; i++) {
uint256 amount = toInvest / length;
IBank(bank).invest(_strategies[bank].at(i), amount);
}
emit Rebalance(bank);
}
/// @notice Finance the next Strategy in the Bank queue with all available underlying
/// @param bank The address of the Bank to finance
/// @dev Only allow this function to be called on approved Banks
function finance(address bank) external override defense onlyBank(bank) {
uint256 length = _strategies[bank].length();
require(length > 0, "Manager: No Strategies");
// get the next Strategy, reset if current index out of bounds
uint8 i;
uint8 queued = _depositQueue[bank];
if (queued < length) {
i = queued;
} else {
i = 0;
}
address strategy = _strategies[bank].at(i);
// finance the strategy, increment index and update delay (+24h)
IBank(bank).investAll(strategy);
_depositQueue[bank] = i + 1;
emit Finance(bank, strategy);
}
/// @notice Evenly finance underlying to all strategies
/// @param bank The address of the Bank to finance
/// @dev Deposit queue not needed here as all Strategies are equally invested in
/// @dev Only allow this function to be called on approved Banks
function financeAll(address bank) external override defense onlyBank(bank) {
uint256 length = _strategies[bank].length();
require(length > 0, "Manager: No Strategies");
uint256 toInvest = IBank(bank).underlyingBalance();
for (uint256 i; i < length; i++) {
uint256 amount = toInvest / length;
IBank(bank).invest(_strategies[bank].at(i), amount);
}
emit FinanceAll(bank);
}
/// @notice Perform a token buyback with accrued revenue
/// @dev Burns all proceeds
/// @param from The address of the token to liquidate for Oh! Tokens
function buyback(address from) external virtual override defense {
// get token, liquidator, and liquidation amount
address _token = token;
address liquidator = liquidators[from][_token];
uint256 amount = IERC20(from).balanceOf(address(this));
// send to liquidator, buyback and burn
TransferHelper.safeTokenTransfer(liquidator, from, amount);
uint256 received = ILiquidator(liquidator).liquidate(address(this), from, _token, amount, 1);
IToken(_token).burn(received);
emit Buyback(from, amount, received);
}
/// @notice Accrue revenue from a Strategy
/// @dev Only callable by approved Strategies
/// @param bank The address of the Bank which uses the Strategy
/// @param amount The total amount of profit received from liquidation
function accrueRevenue(
address bank,
address underlying,
uint256 amount
) external override onlyStrategy(bank, msg.sender) {
// calculate protocol and management fees, find remaining
uint256 fee = amount.mul(buybackFee).div(FEE_DENOMINATOR);
uint256 reward = amount.mul(managementFee).div(FEE_DENOMINATOR);
uint256 remaining = amount.sub(fee).sub(reward);
// send original function caller the management fee, transfer remaining to the Strategy
TransferHelper.safeTokenTransfer(tx.origin, underlying, reward);
TransferHelper.safeTokenTransfer(msg.sender, underlying, remaining);
emit AccrueRevenue(bank, msg.sender, remaining, fee, reward);
}
/// @notice Exit a given strategy for a given bank
/// @param bank The bank that will be used to exit the strategy
/// @param strategy The strategy to be exited
function exit(address bank, address strategy) public onlyGovernance {
IBank(bank).exitAll(strategy);
}
/// @notice Exit from all strategies for a given bank
/// @param bank The bank that will be used to exit the strategy
function exitAll(address bank) public override onlyGovernance {
uint256 length = _strategies[bank].length();
for (uint256 i = 0; i < length; i++) {
IBank(bank).exitAll(_strategies[bank].at(i));
}
}
/// @notice Adds or removes a Bank for investment
/// @dev Only Governance can call this function
/// @param _bank the bank to be approved/unapproved
/// @param _approved the approval status of the bank
function setBank(address _bank, bool _approved) external onlyGovernance {
require(_bank.isContract(), "Manager: Not Contract");
bool approved = _banks.contains(_bank);
require(approved != _approved, "Manager: No Change");
// if Bank is already approved, withdraw all capital
if (approved) {
exitAll(_bank);
_banks.remove(_bank);
} else {
_banks.add(_bank);
}
}
/// @notice Adds or removes a Strategy for a given Bank
/// @param _bank the bank which uses the strategy
/// @param _strategy the strategy to be approved/unapproved
/// @param _approved the approval status of the Strategy
/// @dev Only Governance can call this function
function setStrategy(
address _bank,
address _strategy,
bool _approved
) external onlyGovernance {
require(_strategy.isContract() && _bank.isContract(), "Manager: Not Contract");
bool approved = _strategies[_bank].contains(_strategy);
require(approved != _approved, "Manager: No Change");
// if Strategy is already approved, withdraw all capital
if (approved) {
exit(_bank, _strategy);
_strategies[_bank].remove(_strategy);
} else {
_strategies[_bank].add(_strategy);
}
}
/// @notice Sets the Liquidator contract for a given token
/// @param _liquidator the liquidator contract
/// @param _from the token we have to liquidate
/// @param _to the token we want to receive
/// @dev Only Governance can call this function
function setLiquidator(
address _liquidator,
address _from,
address _to
) external onlyGovernance {
require(_liquidator.isContract(), "Manager: Not Contract");
liquidators[_from][_to] = _liquidator;
}
/// @notice Whitelists strategy for Bank use/management
/// @param _contract the strategy contract
/// @param _whitelisted the whitelisted status of the strategy
/// @dev Only Governance can call this function
function setWhitelisted(address _contract, bool _whitelisted) external onlyGovernance {
require(_contract.isContract(), "Registry: Not Contract");
whitelisted[_contract] = _whitelisted;
}
/// @notice Sets the protocol buyback percentage (Profit Share)
/// @param _buybackFee The new buyback fee
/// @dev Only Governance; base 1000, 1% = 10
function setBuybackFee(uint256 _buybackFee) external onlyGovernance {
require(_buybackFee > MIN_BUYBACK_FEE, "Registry: Invalid Buyback");
require(_buybackFee < MAX_BUYBACK_FEE, "Registry: Buyback Too High");
buybackFee = _buybackFee;
}
/// @notice Sets the protocol management fee percentage
/// @param _managementFee The new management fee
/// @dev Only Governance; base 1000, 1% = 10
function setManagementFee(uint256 _managementFee) external onlyGovernance {
require(_managementFee > MIN_MANAGEMENT_FEE, "Registry: Invalid Mgmt");
require(_managementFee < MAX_MANAGEMENT_FEE, "Registry: Mgmt Too High");
managementFee = _managementFee;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {ISubscriber} from "../interfaces/ISubscriber.sol";
import {IRegistry} from "../interfaces/IRegistry.sol";
/// @title Oh! Finance Subscriber
/// @notice Base Oh! Finance contract used to control access throughout the protocol
abstract contract OhSubscriber is ISubscriber {
address internal _registry;
/// @notice Only allow authorized addresses (governance or manager) to execute a function
modifier onlyAuthorized {
require(msg.sender == governance() || msg.sender == manager(), "Subscriber: Only Authorized");
_;
}
/// @notice Only allow the governance address to execute a function
modifier onlyGovernance {
require(msg.sender == governance(), "Subscriber: Only Governance");
_;
}
/// @notice Construct contract with the Registry
/// @param registry_ The address of the Registry
constructor(address registry_) {
require(Address.isContract(registry_), "Subscriber: Invalid Registry");
_registry = registry_;
}
/// @notice Get the Governance address
/// @return The current Governance address
function governance() public view override returns (address) {
return IRegistry(registry()).governance();
}
/// @notice Get the Manager address
/// @return The current Manager address
function manager() public view override returns (address) {
return IRegistry(registry()).manager();
}
/// @notice Get the Registry address
/// @return The current Registry address
function registry() public view override returns (address) {
return _registry;
}
/// @notice Set the Registry for the contract. Only callable by Governance.
/// @param registry_ The new registry
/// @dev Requires sender to be Governance of the new Registry to avoid bricking.
/// @dev Ideally should not be used
function setRegistry(address registry_) external onlyGovernance {
require(Address.isContract(registry_), "Subscriber: Invalid Registry");
_registry = registry_;
require(msg.sender == governance(), "Subscriber: Bad Governance");
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
library TransferHelper {
using SafeERC20 for IERC20;
// safely transfer tokens without underflowing
function safeTokenTransfer(
address recipient,
address token,
uint256 amount
) internal returns (uint256) {
if (amount == 0) {
return 0;
}
uint256 balance = IERC20(token).balanceOf(address(this));
if (balance < amount) {
IERC20(token).safeTransfer(recipient, balance);
return balance;
} else {
IERC20(token).safeTransfer(recipient, amount);
return amount;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface ILiquidator {
function liquidate(
address recipient,
address from,
address to,
uint256 amount,
uint256 minOut
) external returns (uint256);
function getSwapInfo(address from, address to) external view returns (address router, address[] memory path);
function weth() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IMultichainManager {
function burner() external view returns (address);
function burn() external;
function setBurner(address _burner) external;
function setToken(address _token) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {IBankStorage} from "./IBankStorage.sol";
interface IBank is IBankStorage {
function strategies(uint256 i) external view returns (address);
function totalStrategies() external view returns (uint256);
function underlyingBalance() external view returns (uint256);
function strategyBalance(uint256 i) external view returns (uint256);
function investedBalance() external view returns (uint256);
function virtualBalance() external view returns (uint256);
function virtualPrice() external view returns (uint256);
function pause() external;
function unpause() external;
function setCompound(bool compound) external;
function invest(address strategy, uint256 amount) external;
function investAll(address strategy) external;
function exit(address strategy, uint256 amount) external;
function exitAll(address strategy) external;
function deposit(uint256 amount) external;
function depositFor(uint256 amount, address recipient) external;
function withdraw(uint256 amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IManager {
function token() external view returns (address);
function buybackFee() external view returns (uint256);
function managementFee() external view returns (uint256);
function liquidators(address from, address to) external view returns (address);
function whitelisted(address _contract) external view returns (bool);
function banks(uint256 i) external view returns (address);
function totalBanks() external view returns (uint256);
function strategies(address bank, uint256 i) external view returns (address);
function totalStrategies(address bank) external view returns (uint256);
function withdrawIndex(address bank) external view returns (uint256);
function setWithdrawIndex(uint256 i) external;
function rebalance(address bank) external;
function finance(address bank) external;
function financeAll(address bank) external;
function buyback(address from) external;
function accrueRevenue(
address bank,
address underlying,
uint256 amount
) external;
function exitAll(address bank) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IToken {
function delegate(address delegatee) external;
function delegateBySig(
address delegator,
address delegatee,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function burn(uint256 amount) external;
function mint(address recipient, uint256 amount) external;
function getCurrentVotes(address account) external view returns (uint256);
function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IBankStorage {
function paused() external view returns (bool);
function compound() external view returns (bool);
function underlying() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface ISubscriber {
function registry() external view returns (address);
function governance() external view returns (address);
function manager() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IRegistry {
function governance() external view returns (address);
function manager() external view returns (address);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"registry_","type":"address"},{"internalType":"address","name":"token_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bank","type":"address"},{"indexed":true,"internalType":"address","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"profitAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buybackAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"managementAmount","type":"uint256"}],"name":"AccrueRevenue","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buybackAmount","type":"uint256"}],"name":"Buyback","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bank","type":"address"},{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"Finance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bank","type":"address"}],"name":"FinanceAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bank","type":"address"}],"name":"Rebalance","type":"event"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BUYBACK_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MANAGEMENT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BUYBACK_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_MANAGEMENT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"accrueRevenue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"name":"banks","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"buyback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buybackFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"},{"internalType":"address","name":"strategy","type":"address"}],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"}],"name":"exitAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"}],"name":"finance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"}],"name":"financeAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"liquidators","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managementFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"}],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bank","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setBank","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_burner","type":"address"}],"name":"setBurner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_buybackFee","type":"uint256"}],"name":"setBuybackFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_liquidator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"setLiquidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_managementFee","type":"uint256"}],"name":"setManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registry_","type":"address"}],"name":"setRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bank","type":"address"},{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"setToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"bool","name":"_whitelisted","type":"bool"}],"name":"setWhitelisted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"name":"setWithdrawIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"},{"internalType":"uint256","name":"i","type":"uint256"}],"name":"strategies","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBanks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"}],"name":"totalStrategies","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bank","type":"address"}],"name":"withdrawIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200286538038062002865833981810160405260408110156200003757600080fd5b50805160209182015190918290829082906200005e90829062001f66620000f2821b17901c565b620000b0576040805162461bcd60e51b815260206004820152601c60248201527f537562736372696265723a20496e76616c696420526567697374727900000000604482015290519081900360640190fd5b600080546001600160a01b039283166001600160a01b03199182161790915560018054939092169216919091179055505060c8600255506014600355620000f8565b3b151590565b61275d80620001086000396000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c80639f8f324411610130578063d36b5937116100b8578063f697a0361161007c578063f697a036146105d8578063fb3e6f29146105fe578063fc0c546a14610624578063fd2633901461062c578063fe56e2321461065a57610226565b8063d36b593714610560578063d73792a914610568578063d936547e14610570578063eb0dff66146105aa578063f01cc0a6146105d057610226565b8063a91ee0dc116100ff578063a91ee0dc14610490578063a996d6ce146104b6578063aa4fbf4a146104dc578063b19c0aa314610514578063bae7c80d1461053a57610226565b80639f8f324414610426578063a1b8272314610452578063a625403a1461045a578063a6f7f5d61461048857610226565b806348930428116101b35780637140f2e8116101825780637140f2e8146103ba5780637b103999146103c2578063921c86d2146103ca5780639281aa0b146103f85780639908840c146103ba57610226565b8063489304281461031e5780635aa6e67514610354578063606b473a1461035c5780636ed773431461038257610226565b806327810b6e116101fa57806327810b6e146102cf5780633b2d081c146102d757806344df8e70146102f15780634567bfba146102f9578063481c6a751461031657610226565b806285ae2b1461022b5780630e3da0b814610264578063144fa6d71461028357806321c28191146102a9575b600080fd5b6102486004803603602081101561024157600080fd5b5035610677565b604080516001600160a01b039092168252519081900360200190f35b6102816004803603602081101561027a57600080fd5b503561068a565b005b6102816004803603602081101561029957600080fd5b50356001600160a01b0316610700565b610281600480360360208110156102bf57600080fd5b50356001600160a01b031661077d565b610248610a3a565b6102df610a49565b60408051918252519081900360200190f35b610281610a4f565b6102816004803603602081101561030f57600080fd5b5035610b98565b610248610ca3565b6102816004803603606081101561033457600080fd5b506001600160a01b03813581169160208101359091169060400135610d16565b610248610e51565b6102816004803603602081101561037257600080fd5b50356001600160a01b0316610e93565b6102816004803603606081101561039857600080fd5b506001600160a01b038135811691602081013582169160409091013516611107565b6102df6111f9565b6102486111fe565b610248600480360360408110156103e057600080fd5b506001600160a01b038135811691602001351661120d565b6102816004803603604081101561040e57600080fd5b506001600160a01b0381351690602001351515611233565b6102486004803603604081101561043c57600080fd5b506001600160a01b038135169060200135611315565b6102df61133e565b6102816004803603604081101561047057600080fd5b506001600160a01b0381358116916020013516611344565b6102df61140a565b610281600480360360208110156104a657600080fd5b50356001600160a01b0316611410565b610281600480360360208110156104cc57600080fd5b50356001600160a01b0316611550565b610281600480360360608110156104f257600080fd5b506001600160a01b0381358116916020810135909116906040013515156115cd565b6102df6004803603602081101561052a57600080fd5b50356001600160a01b0316611770565b6102816004803603602081101561055057600080fd5b50356001600160a01b0316611791565b6102df6119ca565b6102df6119cf565b6105966004803603602081101561058657600080fd5b50356001600160a01b03166119d5565b604080519115158252519081900360200190f35b610281600480360360208110156105c057600080fd5b50356001600160a01b03166119ea565b6102df611b03565b6102df600480360360208110156105ee57600080fd5b50356001600160a01b0316611b14565b6102816004803603602081101561061457600080fd5b50356001600160a01b0316611b32565b610248611d16565b6102816004803603604081101561064257600080fd5b506001600160a01b0381351690602001351515611d25565b6102816004803603602081101561067057600080fd5b5035611e63565b6000610684600683611f6c565b92915050565b33610696600682611f78565b6106dc576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b50336000908152600a60205260409020805460ff191660ff92909216919091179055565b610708610e51565b6001600160a01b0316336001600160a01b03161461075b576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b3332148061079a57503360009081526005602052604090205460ff165b6107d9576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b806107e5600682611f78565b61082b576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b6001600160a01b038216600090815260086020526040812061084c90611f8d565b905060005b818110156108e4576001600160a01b038416600081815260086020526040902063eb0dff66906108819084611f6c565b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156108c057600080fd5b505af11580156108d4573d6000803e3d6000fd5b5050600190920191506108519050565b506000836001600160a01b03166359356c5c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561092057600080fd5b505afa158015610934573d6000803e3d6000fd5b505050506040513d602081101561094a57600080fd5b5051905060005b828110156109ff57600083838161096457fe5b6001600160a01b03881660008181526008602052604090209290910492509063b9b8c246906109939085611f6c565b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156109da57600080fd5b505af11580156109ee573d6000803e3d6000fd5b505060019093019250610951915050565b506040516001600160a01b038516907fa61bd16ebda9d1c8ec2a61970b39e6640e55ed8433a22765a1b5217b72c4a81290600090a250505050565b600b546001600160a01b031681565b60025481565b33321480610a6c57503360009081526005602052604090205460ff165b610aab576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b600b546001600160a01b0316610afd576040805162461bcd60e51b815260206004820152601260248201527126b0b730b3b2b91d10273790213ab93732b960711b604482015290519081900360640190fd5b600154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610b4857600080fd5b505afa158015610b5c573d6000803e3d6000fd5b505050506040513d6020811015610b7257600080fd5b5051600b54600154919250610b94916001600160a01b03918216911683611f98565b5050565b610ba0610e51565b6001600160a01b0316336001600160a01b031614610bf3576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b60648111610c48576040805162461bcd60e51b815260206004820152601960248201527f52656769737472793a20496e76616c6964204275796261636b00000000000000604482015290519081900360640190fd5b6101f48110610c9e576040805162461bcd60e51b815260206004820152601a60248201527f52656769737472793a204275796261636b20546f6f2048696768000000000000604482015290519081900360640190fd5b600255565b6000610cad6111fe565b6001600160a01b031663481c6a756040518163ffffffff1660e01b815260040160206040518083038186803b158015610ce557600080fd5b505afa158015610cf9573d6000803e3d6000fd5b505050506040513d6020811015610d0f57600080fd5b5051905090565b6001600160a01b038316600090815260086020526040902083903390610d3c9082611f78565b610d86576040805162461bcd60e51b81526020600482015260166024820152754d616e616765723a204f6e6c7920537472617465677960501b604482015290519081900360640190fd5b6000610da96103e8610da36002548761206490919063ffffffff16565b906120bd565b90506000610dc86103e8610da36003548861206490919063ffffffff16565b90506000610de082610dda8886612124565b90612124565b9050610ded328884611f98565b50610df9338883611f98565b506040805182815260208101859052808201849052905133916001600160a01b038b16917faa199a16983a8f166eb461939bd1b0bd1881e692fa38dbb98bd89c856052cd849181900360600190a35050505050505050565b6000610e5b6111fe565b6001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b158015610ce557600080fd5b33321480610eb057503360009081526005602052604090205460ff165b610eef576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b80610efb600682611f78565b610f41576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b6001600160a01b0382166000908152600860205260408120610f6290611f8d565b905060008111610fb2576040805162461bcd60e51b81526020600482015260166024820152754d616e616765723a204e6f205374726174656769657360501b604482015290519081900360640190fd5b6000836001600160a01b03166359356c5c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fed57600080fd5b505afa158015611001573d6000803e3d6000fd5b505050506040513d602081101561101757600080fd5b5051905060005b828110156110cc57600083838161103157fe5b6001600160a01b03881660008181526008602052604090209290910492509063b9b8c246906110609085611f6c565b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156110a757600080fd5b505af11580156110bb573d6000803e3d6000fd5b50506001909301925061101e915050565b506040516001600160a01b038516907fb888c73f8596c5d056c9c67c35e5ed784af064b3112cd851b2b860f9c2b6ccc990600090a250505050565b61110f610e51565b6001600160a01b0316336001600160a01b031614611162576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b611174836001600160a01b0316611f66565b6111bd576040805162461bcd60e51b815260206004820152601560248201527413585b9859d95c8e88139bdd0810dbdb9d1c9858dd605a1b604482015290519081900360640190fd5b6001600160a01b0391821660009081526004602090815260408083209385168352929052208054919092166001600160a01b0319909116179055565b606481565b6000546001600160a01b031690565b60046020908152600092835260408084209091529082529020546001600160a01b031681565b61123b610e51565b6001600160a01b0316336001600160a01b03161461128e576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b6112a0826001600160a01b0316611f66565b6112ea576040805162461bcd60e51b8152602060048201526016602482015275149959da5cdd1c9e4e88139bdd0810dbdb9d1c9858dd60521b604482015290519081900360640190fd5b6001600160a01b03919091166000908152600560205260409020805460ff1916911515919091179055565b6001600160a01b03821660009081526008602052604081206113379083611f6c565b9392505050565b6101f481565b61134c610e51565b6001600160a01b0316336001600160a01b03161461139f576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b816001600160a01b031663eb0dff66826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156113ee57600080fd5b505af1158015611402573d6000803e3d6000fd5b505050505050565b60035481565b611418610e51565b6001600160a01b0316336001600160a01b03161461146b576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b61147481611f66565b6114c5576040805162461bcd60e51b815260206004820152601c60248201527f537562736372696265723a20496e76616c696420526567697374727900000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0383161790556114e8610e51565b6001600160a01b0316336001600160a01b03161461154d576040805162461bcd60e51b815260206004820152601a60248201527f537562736372696265723a2042616420476f7665726e616e6365000000000000604482015290519081900360640190fd5b50565b611558610e51565b6001600160a01b0316336001600160a01b0316146115ab576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6115d5610e51565b6001600160a01b0316336001600160a01b031614611628576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b61163a826001600160a01b0316611f66565b80156116535750611653836001600160a01b0316611f66565b61169c576040805162461bcd60e51b815260206004820152601560248201527413585b9859d95c8e88139bdd0810dbdb9d1c9858dd605a1b604482015290519081900360640190fd5b6001600160a01b03831660009081526008602052604081206116be9084611f78565b9050811515811515141561170e576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204e6f204368616e676560701b604482015290519081900360640190fd5b80156117465761171e8484611344565b6001600160a01b03841660009081526008602052604090206117409084612181565b5061176a565b6001600160a01b03841660009081526008602052604090206117689084612196565b505b50505050565b6001600160a01b038116600090815260086020526040812061068490611f8d565b333214806117ae57503360009081526005602052604090205460ff165b6117ed576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b806117f9600682611f78565b61183f576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b6001600160a01b038216600090815260086020526040812061186090611f8d565b9050600081116118b0576040805162461bcd60e51b81526020600482015260166024820152754d616e616765723a204e6f205374726174656769657360501b604482015290519081900360640190fd5b6001600160a01b03831660009081526009602052604081205460ff16828110156118dc578091506118e1565b600091505b6001600160a01b03851660009081526008602052604081206119069060ff8516611f6c565b9050856001600160a01b031663753842db826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561195757600080fd5b505af115801561196b573d6000803e3d6000fd5b505050506001600160a01b03868116600081815260096020526040808220805460ff19166001890160ff1617905551928416927fffdb70e99f7f3262c2641a400deab1ad02aa7c2a59e0be6a116e71867296b20b9190a3505050505050565b600081565b6103e881565b60056020526000908152604090205460ff1681565b6119f2610e51565b6001600160a01b0316336001600160a01b031614611a45576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b6001600160a01b0381166000908152600860205260408120611a6690611f8d565b905060005b81811015611afe576001600160a01b038316600081815260086020526040902063eb0dff6690611a9b9084611f6c565b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b158015611ada57600080fd5b505af1158015611aee573d6000803e3d6000fd5b505060019092019150611a6b9050565b505050565b6000611b0f6006611f8d565b905090565b6001600160a01b03166000908152600a602052604090205460ff1690565b33321480611b4f57503360009081526005602052604090205460ff165b611b8e576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b6001546001600160a01b0382811660008181526004602081815260408084209686168085529682528084205481516370a0823160e01b8152309481019490945290519516949293926370a08231926024808201939291829003018186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d6020811015611c2257600080fd5b50519050611c31828583611f98565b5060408051636f70e66f60e01b81523060048201526001600160a01b038681166024830152858116604483015260648201849052600160848301529151600092851691636f70e66f9160a480830192602092919082900301818787803b158015611c9a57600080fd5b505af1158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b5051604080518481526020810183905281519293506001600160a01b038816927f2dcc2439519c7d06fca9f8ae01e07f4f3c6ca21b5cdf8eff42cb75cf34d223c9929181900390910190a25050505050565b6001546001600160a01b031681565b611d2d610e51565b6001600160a01b0316336001600160a01b031614611d80576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b611d92826001600160a01b0316611f66565b611ddb576040805162461bcd60e51b815260206004820152601560248201527413585b9859d95c8e88139bdd0810dbdb9d1c9858dd605a1b604482015290519081900360640190fd5b6000611de8600684611f78565b90508115158115151415611e38576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204e6f204368616e676560701b604482015290519081900360640190fd5b8015611e5857611e47836119ea565b611e52600684612181565b50611afe565b61176a600684612196565b611e6b610e51565b6001600160a01b0316336001600160a01b031614611ebe576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b60008111611f0c576040805162461bcd60e51b8152602060048201526016602482015275149959da5cdd1c9e4e88125b9d985b1a59081359db5d60521b604482015290519081900360640190fd5b60648110611f61576040805162461bcd60e51b815260206004820152601760248201527f52656769737472793a204d676d7420546f6f2048696768000000000000000000604482015290519081900360640190fd5b600355565b3b151590565b600061133783836121ab565b6000611337836001600160a01b03841661220f565b600061068482612227565b600081611fa757506000611337565b6000836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611ff657600080fd5b505afa15801561200a573d6000803e3d6000fd5b505050506040513d602081101561202057600080fd5b5051905082811015612047576120406001600160a01b038516868361222b565b9050611337565b61205b6001600160a01b038516868561222b565b50909392505050565b60008261207357506000610684565b8282028284828161208057fe5b04146113375760405162461bcd60e51b81526004018080602001828103825260218152602001806126bd6021913960400191505060405180910390fd5b6000808211612113576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161211c57fe5b049392505050565b60008282111561217b576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000611337836001600160a01b03841661227d565b6000611337836001600160a01b038416612343565b815460009082106121ed5760405162461bcd60e51b81526004018080602001828103825260228152602001806126556022913960400191505060405180910390fd5b8260000182815481106121fc57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611afe90849061238d565b6000818152600183016020526040812054801561233957835460001980830191908101906000908790839081106122b057fe5b90600052602060002001549050808760000184815481106122cd57fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806122fd57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610684565b6000915050610684565b600061234f838361220f565b61238557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610684565b506000610684565b60006123e2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661243e9092919063ffffffff16565b805190915015611afe5780806020019051602081101561240157600080fd5b5051611afe5760405162461bcd60e51b815260040180806020018281038252602a8152602001806126fe602a913960400191505060405180910390fd5b606061244d8484600085612455565b949350505050565b6060824710156124965760405162461bcd60e51b81526004018080602001828103825260268152602001806126776026913960400191505060405180910390fd5b61249f85611f66565b6124f0576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b6020831061252e5780518252601f19909201916020918201910161250f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612590576040519150601f19603f3d011682016040523d82523d6000602084013e612595565b606091505b50915091506125a58282866125b0565b979650505050505050565b606083156125bf575081611337565b8251156125cf5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612619578181015183820152602001612601565b50505050905090810190601f1680156126465780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c537562736372696265723a204f6e6c7920476f7665726e616e63650000000000536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774d616e616765723a204f6e6c7920454f41206f722057686974656c69737400005361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220d0309832469b7f51b30d0b40eb15a21055312ee89a5157984c97aea15f31f55e64736f6c634300070600330000000000000000000000006da30b09763f54ff35dab317a0c987b0276f50ff0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102265760003560e01c80639f8f324411610130578063d36b5937116100b8578063f697a0361161007c578063f697a036146105d8578063fb3e6f29146105fe578063fc0c546a14610624578063fd2633901461062c578063fe56e2321461065a57610226565b8063d36b593714610560578063d73792a914610568578063d936547e14610570578063eb0dff66146105aa578063f01cc0a6146105d057610226565b8063a91ee0dc116100ff578063a91ee0dc14610490578063a996d6ce146104b6578063aa4fbf4a146104dc578063b19c0aa314610514578063bae7c80d1461053a57610226565b80639f8f324414610426578063a1b8272314610452578063a625403a1461045a578063a6f7f5d61461048857610226565b806348930428116101b35780637140f2e8116101825780637140f2e8146103ba5780637b103999146103c2578063921c86d2146103ca5780639281aa0b146103f85780639908840c146103ba57610226565b8063489304281461031e5780635aa6e67514610354578063606b473a1461035c5780636ed773431461038257610226565b806327810b6e116101fa57806327810b6e146102cf5780633b2d081c146102d757806344df8e70146102f15780634567bfba146102f9578063481c6a751461031657610226565b806285ae2b1461022b5780630e3da0b814610264578063144fa6d71461028357806321c28191146102a9575b600080fd5b6102486004803603602081101561024157600080fd5b5035610677565b604080516001600160a01b039092168252519081900360200190f35b6102816004803603602081101561027a57600080fd5b503561068a565b005b6102816004803603602081101561029957600080fd5b50356001600160a01b0316610700565b610281600480360360208110156102bf57600080fd5b50356001600160a01b031661077d565b610248610a3a565b6102df610a49565b60408051918252519081900360200190f35b610281610a4f565b6102816004803603602081101561030f57600080fd5b5035610b98565b610248610ca3565b6102816004803603606081101561033457600080fd5b506001600160a01b03813581169160208101359091169060400135610d16565b610248610e51565b6102816004803603602081101561037257600080fd5b50356001600160a01b0316610e93565b6102816004803603606081101561039857600080fd5b506001600160a01b038135811691602081013582169160409091013516611107565b6102df6111f9565b6102486111fe565b610248600480360360408110156103e057600080fd5b506001600160a01b038135811691602001351661120d565b6102816004803603604081101561040e57600080fd5b506001600160a01b0381351690602001351515611233565b6102486004803603604081101561043c57600080fd5b506001600160a01b038135169060200135611315565b6102df61133e565b6102816004803603604081101561047057600080fd5b506001600160a01b0381358116916020013516611344565b6102df61140a565b610281600480360360208110156104a657600080fd5b50356001600160a01b0316611410565b610281600480360360208110156104cc57600080fd5b50356001600160a01b0316611550565b610281600480360360608110156104f257600080fd5b506001600160a01b0381358116916020810135909116906040013515156115cd565b6102df6004803603602081101561052a57600080fd5b50356001600160a01b0316611770565b6102816004803603602081101561055057600080fd5b50356001600160a01b0316611791565b6102df6119ca565b6102df6119cf565b6105966004803603602081101561058657600080fd5b50356001600160a01b03166119d5565b604080519115158252519081900360200190f35b610281600480360360208110156105c057600080fd5b50356001600160a01b03166119ea565b6102df611b03565b6102df600480360360208110156105ee57600080fd5b50356001600160a01b0316611b14565b6102816004803603602081101561061457600080fd5b50356001600160a01b0316611b32565b610248611d16565b6102816004803603604081101561064257600080fd5b506001600160a01b0381351690602001351515611d25565b6102816004803603602081101561067057600080fd5b5035611e63565b6000610684600683611f6c565b92915050565b33610696600682611f78565b6106dc576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b50336000908152600a60205260409020805460ff191660ff92909216919091179055565b610708610e51565b6001600160a01b0316336001600160a01b03161461075b576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b3332148061079a57503360009081526005602052604090205460ff165b6107d9576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b806107e5600682611f78565b61082b576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b6001600160a01b038216600090815260086020526040812061084c90611f8d565b905060005b818110156108e4576001600160a01b038416600081815260086020526040902063eb0dff66906108819084611f6c565b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156108c057600080fd5b505af11580156108d4573d6000803e3d6000fd5b5050600190920191506108519050565b506000836001600160a01b03166359356c5c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561092057600080fd5b505afa158015610934573d6000803e3d6000fd5b505050506040513d602081101561094a57600080fd5b5051905060005b828110156109ff57600083838161096457fe5b6001600160a01b03881660008181526008602052604090209290910492509063b9b8c246906109939085611f6c565b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156109da57600080fd5b505af11580156109ee573d6000803e3d6000fd5b505060019093019250610951915050565b506040516001600160a01b038516907fa61bd16ebda9d1c8ec2a61970b39e6640e55ed8433a22765a1b5217b72c4a81290600090a250505050565b600b546001600160a01b031681565b60025481565b33321480610a6c57503360009081526005602052604090205460ff165b610aab576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b600b546001600160a01b0316610afd576040805162461bcd60e51b815260206004820152601260248201527126b0b730b3b2b91d10273790213ab93732b960711b604482015290519081900360640190fd5b600154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610b4857600080fd5b505afa158015610b5c573d6000803e3d6000fd5b505050506040513d6020811015610b7257600080fd5b5051600b54600154919250610b94916001600160a01b03918216911683611f98565b5050565b610ba0610e51565b6001600160a01b0316336001600160a01b031614610bf3576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b60648111610c48576040805162461bcd60e51b815260206004820152601960248201527f52656769737472793a20496e76616c6964204275796261636b00000000000000604482015290519081900360640190fd5b6101f48110610c9e576040805162461bcd60e51b815260206004820152601a60248201527f52656769737472793a204275796261636b20546f6f2048696768000000000000604482015290519081900360640190fd5b600255565b6000610cad6111fe565b6001600160a01b031663481c6a756040518163ffffffff1660e01b815260040160206040518083038186803b158015610ce557600080fd5b505afa158015610cf9573d6000803e3d6000fd5b505050506040513d6020811015610d0f57600080fd5b5051905090565b6001600160a01b038316600090815260086020526040902083903390610d3c9082611f78565b610d86576040805162461bcd60e51b81526020600482015260166024820152754d616e616765723a204f6e6c7920537472617465677960501b604482015290519081900360640190fd5b6000610da96103e8610da36002548761206490919063ffffffff16565b906120bd565b90506000610dc86103e8610da36003548861206490919063ffffffff16565b90506000610de082610dda8886612124565b90612124565b9050610ded328884611f98565b50610df9338883611f98565b506040805182815260208101859052808201849052905133916001600160a01b038b16917faa199a16983a8f166eb461939bd1b0bd1881e692fa38dbb98bd89c856052cd849181900360600190a35050505050505050565b6000610e5b6111fe565b6001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b158015610ce557600080fd5b33321480610eb057503360009081526005602052604090205460ff165b610eef576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b80610efb600682611f78565b610f41576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b6001600160a01b0382166000908152600860205260408120610f6290611f8d565b905060008111610fb2576040805162461bcd60e51b81526020600482015260166024820152754d616e616765723a204e6f205374726174656769657360501b604482015290519081900360640190fd5b6000836001600160a01b03166359356c5c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fed57600080fd5b505afa158015611001573d6000803e3d6000fd5b505050506040513d602081101561101757600080fd5b5051905060005b828110156110cc57600083838161103157fe5b6001600160a01b03881660008181526008602052604090209290910492509063b9b8c246906110609085611f6c565b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156110a757600080fd5b505af11580156110bb573d6000803e3d6000fd5b50506001909301925061101e915050565b506040516001600160a01b038516907fb888c73f8596c5d056c9c67c35e5ed784af064b3112cd851b2b860f9c2b6ccc990600090a250505050565b61110f610e51565b6001600160a01b0316336001600160a01b031614611162576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b611174836001600160a01b0316611f66565b6111bd576040805162461bcd60e51b815260206004820152601560248201527413585b9859d95c8e88139bdd0810dbdb9d1c9858dd605a1b604482015290519081900360640190fd5b6001600160a01b0391821660009081526004602090815260408083209385168352929052208054919092166001600160a01b0319909116179055565b606481565b6000546001600160a01b031690565b60046020908152600092835260408084209091529082529020546001600160a01b031681565b61123b610e51565b6001600160a01b0316336001600160a01b03161461128e576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b6112a0826001600160a01b0316611f66565b6112ea576040805162461bcd60e51b8152602060048201526016602482015275149959da5cdd1c9e4e88139bdd0810dbdb9d1c9858dd60521b604482015290519081900360640190fd5b6001600160a01b03919091166000908152600560205260409020805460ff1916911515919091179055565b6001600160a01b03821660009081526008602052604081206113379083611f6c565b9392505050565b6101f481565b61134c610e51565b6001600160a01b0316336001600160a01b03161461139f576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b816001600160a01b031663eb0dff66826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b1580156113ee57600080fd5b505af1158015611402573d6000803e3d6000fd5b505050505050565b60035481565b611418610e51565b6001600160a01b0316336001600160a01b03161461146b576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b61147481611f66565b6114c5576040805162461bcd60e51b815260206004820152601c60248201527f537562736372696265723a20496e76616c696420526567697374727900000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0383161790556114e8610e51565b6001600160a01b0316336001600160a01b03161461154d576040805162461bcd60e51b815260206004820152601a60248201527f537562736372696265723a2042616420476f7665726e616e6365000000000000604482015290519081900360640190fd5b50565b611558610e51565b6001600160a01b0316336001600160a01b0316146115ab576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6115d5610e51565b6001600160a01b0316336001600160a01b031614611628576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b61163a826001600160a01b0316611f66565b80156116535750611653836001600160a01b0316611f66565b61169c576040805162461bcd60e51b815260206004820152601560248201527413585b9859d95c8e88139bdd0810dbdb9d1c9858dd605a1b604482015290519081900360640190fd5b6001600160a01b03831660009081526008602052604081206116be9084611f78565b9050811515811515141561170e576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204e6f204368616e676560701b604482015290519081900360640190fd5b80156117465761171e8484611344565b6001600160a01b03841660009081526008602052604090206117409084612181565b5061176a565b6001600160a01b03841660009081526008602052604090206117689084612196565b505b50505050565b6001600160a01b038116600090815260086020526040812061068490611f8d565b333214806117ae57503360009081526005602052604090205460ff165b6117ed576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b806117f9600682611f78565b61183f576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204f6e6c792042616e6b60701b604482015290519081900360640190fd5b6001600160a01b038216600090815260086020526040812061186090611f8d565b9050600081116118b0576040805162461bcd60e51b81526020600482015260166024820152754d616e616765723a204e6f205374726174656769657360501b604482015290519081900360640190fd5b6001600160a01b03831660009081526009602052604081205460ff16828110156118dc578091506118e1565b600091505b6001600160a01b03851660009081526008602052604081206119069060ff8516611f6c565b9050856001600160a01b031663753842db826040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b15801561195757600080fd5b505af115801561196b573d6000803e3d6000fd5b505050506001600160a01b03868116600081815260096020526040808220805460ff19166001890160ff1617905551928416927fffdb70e99f7f3262c2641a400deab1ad02aa7c2a59e0be6a116e71867296b20b9190a3505050505050565b600081565b6103e881565b60056020526000908152604090205460ff1681565b6119f2610e51565b6001600160a01b0316336001600160a01b031614611a45576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b6001600160a01b0381166000908152600860205260408120611a6690611f8d565b905060005b81811015611afe576001600160a01b038316600081815260086020526040902063eb0dff6690611a9b9084611f6c565b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b158015611ada57600080fd5b505af1158015611aee573d6000803e3d6000fd5b505060019092019150611a6b9050565b505050565b6000611b0f6006611f8d565b905090565b6001600160a01b03166000908152600a602052604090205460ff1690565b33321480611b4f57503360009081526005602052604090205460ff165b611b8e576040805162461bcd60e51b815260206004820152601e60248201526000805160206126de833981519152604482015290519081900360640190fd5b6001546001600160a01b0382811660008181526004602081815260408084209686168085529682528084205481516370a0823160e01b8152309481019490945290519516949293926370a08231926024808201939291829003018186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d6020811015611c2257600080fd5b50519050611c31828583611f98565b5060408051636f70e66f60e01b81523060048201526001600160a01b038681166024830152858116604483015260648201849052600160848301529151600092851691636f70e66f9160a480830192602092919082900301818787803b158015611c9a57600080fd5b505af1158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b5051604080518481526020810183905281519293506001600160a01b038816927f2dcc2439519c7d06fca9f8ae01e07f4f3c6ca21b5cdf8eff42cb75cf34d223c9929181900390910190a25050505050565b6001546001600160a01b031681565b611d2d610e51565b6001600160a01b0316336001600160a01b031614611d80576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b611d92826001600160a01b0316611f66565b611ddb576040805162461bcd60e51b815260206004820152601560248201527413585b9859d95c8e88139bdd0810dbdb9d1c9858dd605a1b604482015290519081900360640190fd5b6000611de8600684611f78565b90508115158115151415611e38576040805162461bcd60e51b81526020600482015260126024820152714d616e616765723a204e6f204368616e676560701b604482015290519081900360640190fd5b8015611e5857611e47836119ea565b611e52600684612181565b50611afe565b61176a600684612196565b611e6b610e51565b6001600160a01b0316336001600160a01b031614611ebe576040805162461bcd60e51b815260206004820152601b602482015260008051602061269d833981519152604482015290519081900360640190fd5b60008111611f0c576040805162461bcd60e51b8152602060048201526016602482015275149959da5cdd1c9e4e88125b9d985b1a59081359db5d60521b604482015290519081900360640190fd5b60648110611f61576040805162461bcd60e51b815260206004820152601760248201527f52656769737472793a204d676d7420546f6f2048696768000000000000000000604482015290519081900360640190fd5b600355565b3b151590565b600061133783836121ab565b6000611337836001600160a01b03841661220f565b600061068482612227565b600081611fa757506000611337565b6000836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611ff657600080fd5b505afa15801561200a573d6000803e3d6000fd5b505050506040513d602081101561202057600080fd5b5051905082811015612047576120406001600160a01b038516868361222b565b9050611337565b61205b6001600160a01b038516868561222b565b50909392505050565b60008261207357506000610684565b8282028284828161208057fe5b04146113375760405162461bcd60e51b81526004018080602001828103825260218152602001806126bd6021913960400191505060405180910390fd5b6000808211612113576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161211c57fe5b049392505050565b60008282111561217b576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000611337836001600160a01b03841661227d565b6000611337836001600160a01b038416612343565b815460009082106121ed5760405162461bcd60e51b81526004018080602001828103825260228152602001806126556022913960400191505060405180910390fd5b8260000182815481106121fc57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611afe90849061238d565b6000818152600183016020526040812054801561233957835460001980830191908101906000908790839081106122b057fe5b90600052602060002001549050808760000184815481106122cd57fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806122fd57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610684565b6000915050610684565b600061234f838361220f565b61238557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610684565b506000610684565b60006123e2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661243e9092919063ffffffff16565b805190915015611afe5780806020019051602081101561240157600080fd5b5051611afe5760405162461bcd60e51b815260040180806020018281038252602a8152602001806126fe602a913960400191505060405180910390fd5b606061244d8484600085612455565b949350505050565b6060824710156124965760405162461bcd60e51b81526004018080602001828103825260268152602001806126776026913960400191505060405180910390fd5b61249f85611f66565b6124f0576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b6020831061252e5780518252601f19909201916020918201910161250f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612590576040519150601f19603f3d011682016040523d82523d6000602084013e612595565b606091505b50915091506125a58282866125b0565b979650505050505050565b606083156125bf575081611337565b8251156125cf5782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612619578181015183820152602001612601565b50505050905090810190601f1680156126465780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c537562736372696265723a204f6e6c7920476f7665726e616e63650000000000536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774d616e616765723a204f6e6c7920454f41206f722057686974656c69737400005361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220d0309832469b7f51b30d0b40eb15a21055312ee89a5157984c97aea15f31f55e64736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006da30b09763f54ff35dab317a0c987b0276f50ff0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : registry_ (address): 0x6Da30B09763f54ff35daB317a0C987B0276F50FF
Arg [1] : token_ (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000006da30b09763f54ff35dab317a0c987b0276f50ff
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MOVR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.