Transaction Hash:
Block:
13786126 at Dec-11-2021 08:53:54 PM +UTC
Transaction Fee:
0.00307768672890952 ETH
$9.68
Gas Used:
47,440 Gas / 64.875352633 Gwei
Emitted Events:
500 |
RegistryProxy.LogUnpauseVault( vault=0x6d8bfdb4c4975bb086fc9027e48d5775f609ff88, unpaused=True, caller=[Sender] 0x6bd60f089b6e8ba75c409a54cdea34aa511277f6 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x6bd60f08...A511277f6 |
26.717399421641134994 Eth
Nonce: 97
|
26.714321734912225474 Eth
Nonce: 98
| 0.00307768672890952 | ||
0x99fa011E...96BA67fE3 | |||||
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 6,917.593300546768742872 Eth | 6,917.593371706768742872 Eth | 0.00007116 |
Execution Trace
RegistryProxy.1c11fb82( )
0x9ff914d0005564a941429d1685477851d1836672.1c11fb82( )
0x6d8bfdb4c4975bb086fc9027e48d5775f609ff88.37d62e54( )
-
0xfad37e3197e6331647030954512964cd2e55acaf.37d62e54( )
-
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; // helper contracts import { RegistryStorage } from "./RegistryStorage.sol"; import { ModifiersController } from "./ModifiersController.sol"; /** * @title RegistryProxy Contract * @author Opty.fi * @dev Storage for the Registry is at this address, * while execution is delegated to the `registryImplementation`. * Registry should reference this contract as their controller. * It defines a fallback function that delegates all calls to the address * returned by the abstract _implementation() internal function. */ contract RegistryProxy is RegistryStorage, ModifiersController { /** * @notice Emitted when pendingComptrollerImplementation is changed * @param oldPendingImplementation Old Registry contract's implementation address which is still pending * @param newPendingImplementation New Registry contract's implementation address which is still pending */ event NewPendingImplementation(address oldPendingImplementation, address newPendingImplementation); /** * @notice Emitted when pendingComptrollerImplementation is updated * @param oldImplementation Old Registry Contract's implementation address * @param newImplementation New Registry Contract's implementation address */ event NewImplementation(address oldImplementation, address newImplementation); /** * @notice Emitted when pendingGovernance is changed * @param oldPendingGovernance Old Governance's address which is still pending * @param newPendingGovernance New Governance's address which is still pending */ event NewPendingGovernance(address oldPendingGovernance, address newPendingGovernance); /** * @notice Emitted when pendingGovernance is accepted, which means governance is updated * @param oldGovernance Old Governance's address * @param newGovernance New Governance's address */ event NewGovernance(address oldGovernance, address newGovernance); constructor() public { governance = msg.sender; setFinanceOperator(msg.sender); setRiskOperator(msg.sender); setStrategyOperator(msg.sender); setOperator(msg.sender); } /* solhint-disable */ receive() external payable { revert(); } /** * @notice Delegates execution to an implementation contract * @dev Returns to external caller whatever implementation returns or forwards reverts */ fallback() external payable { // delegate all other functions to current implementation (bool success, ) = registryImplementation.delegatecall(msg.data); assembly { let free_mem_ptr := mload(0x40) returndatacopy(free_mem_ptr, 0, returndatasize()) switch success case 0 { revert(free_mem_ptr, returndatasize()) } default { return(free_mem_ptr, returndatasize()) } } } /* solhint-disable */ /*** Admin Functions ***/ /** * @dev Set the registry contract as pending implementation initally * @param newPendingImplementation registry address to act as pending implementation */ function setPendingImplementation(address newPendingImplementation) external onlyOperator { address oldPendingImplementation = pendingRegistryImplementation; pendingRegistryImplementation = newPendingImplementation; emit NewPendingImplementation(oldPendingImplementation, pendingRegistryImplementation); } /** * @notice Accepts new implementation of registry * @dev Governance function for new implementation to accept it's role as implementation */ function acceptImplementation() external returns (uint256) { // Check caller is pendingImplementation and pendingImplementation ≠ address(0) require( msg.sender == pendingRegistryImplementation && pendingRegistryImplementation != address(0), "!pendingRegistryImplementation" ); // Save current values for inclusion in log address oldImplementation = registryImplementation; address oldPendingImplementation = pendingRegistryImplementation; registryImplementation = pendingRegistryImplementation; pendingRegistryImplementation = address(0); emit NewImplementation(oldImplementation, registryImplementation); emit NewPendingImplementation(oldPendingImplementation, pendingRegistryImplementation); return uint256(0); } /** * @notice Transfers the governance rights * @dev The newPendingGovernance must call acceptGovernance() to finalize the transfer * @param newPendingGovernance New pending governance address */ function setPendingGovernance(address newPendingGovernance) external onlyOperator { // Save current value, if any, for inclusion in log address oldPendingGovernance = pendingGovernance; // Store pendingGovernance with value newPendingGovernance pendingGovernance = newPendingGovernance; // Emit NewPendingGovernance(oldPendingGovernance, newPendingGovernance) emit NewPendingGovernance(oldPendingGovernance, newPendingGovernance); } /** * @notice Accepts transfer of Governance rights * @dev Governance function for pending governance to accept role and update Governance */ function acceptGovernance() external returns (uint256) { require(msg.sender == pendingGovernance && msg.sender != address(0), "!pendingGovernance"); // Save current values for inclusion in log address oldGovernance = governance; address oldPendingGovernance = pendingGovernance; // Store admin with value pendingGovernance governance = pendingGovernance; // Clear the pending value pendingGovernance = address(0); emit NewGovernance(oldGovernance, governance); emit NewPendingGovernance(oldPendingGovernance, pendingGovernance); return uint256(0); } } /* solhint-disable max-states-count */ // SPDX-License-Identifier: MIT pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; // libraries import { DataTypes } from "../../libraries/types/DataTypes.sol"; /** * @title RegistryAdminStorage Contract * @author Opty.fi * @dev Contract used to store registry's admin account */ contract RegistryAdminStorage { /** * @notice Governance of optyfi's earn protocol */ address public governance; /** * @notice Finance operator of optyfi's earn protocol * @dev Handle functions having withdrawal fee, treasury and finance related logic */ address public financeOperator; /** * @notice Risk operator of optyfi's earn protocol * @dev Handle functions for maintaining the risk profiles and rating of liquidity/credit pools */ address public riskOperator; /** * @notice Strategy operator of optyfi's earn protocol * @dev Handle functions related to strategies/vault strategies to be used */ address public strategyOperator; /** * @notice Operator of optyfi's earn protocol */ address public operator; /** * @notice Treasury of optyfi's earn protocol */ address public treasury; /** * @notice Distributor for OPTY token */ address public optyDistributor; /** * @notice Pending governance for optyfi's earn protocol */ address public pendingGovernance; /** * @notice Active brains of Registry */ address public registryImplementation; /** * @notice Pending brains of Registry */ address public pendingRegistryImplementation; /** * @notice notify when transfer operation of financeOperator occurs * @param financeOperator address of Finance operator of optyfi's earn protocol * @param caller address of user who has called the respective function to trigger this event */ event TransferFinanceOperator(address indexed financeOperator, address indexed caller); /** * @notice notify when transfer operation of riskOperator occurs * @param riskOperator address of Risk operator of optyfi's earn protocol * @param caller address of user who has called the respective function to trigger this event */ event TransferRiskOperator(address indexed riskOperator, address indexed caller); /** * @notice notify when transfer operation of strategyOperator occurs * @param strategyOperator address of Strategy operator of optyfi's earn protocol * @param caller address of user who has called the respective function to trigger this event */ event TransferStrategyOperator(address indexed strategyOperator, address indexed caller); /** * @notice notify when transfer operation of operator occurs * @param operator address of Operator of optyfi's earn protocol * @param caller address of user who has called the respective function to trigger this event */ event TransferOperator(address indexed operator, address indexed caller); /** * @notice notify when transfer operation of treasury occurs * @param treasury address of Treasury of optyfi's earn protocol * @param caller address of user who has called the respective function to trigger this event */ event TransferTreasury(address indexed treasury, address indexed caller); /** * @notice notify when transfer operation of optyDistributor occurs * @param optyDistributor address of Opty distributor of optyfi's earn protocol * @param caller address of user who has called the respective function to trigger this event */ event TransferOPTYDistributor(address indexed optyDistributor, address indexed caller); } /** * @title RegistryStorage Contract * @author Opty.fi * @dev Contract used to store registry's contract state variables and events */ contract RegistryStorage is RegistryAdminStorage { /** * @notice token address status which are approved or not */ mapping(address => bool) public tokens; /** * @notice token data mapped to token/tokens address/addresses hash */ mapping(bytes32 => DataTypes.Token) public tokensHashToTokens; /** * @notice liquidityPool address mapped to its struct having `pool`, `outputToken`, `isBorrow` */ mapping(address => DataTypes.LiquidityPool) public liquidityPools; /** * @notice creaditPool address mapped to its struct having `pool`, `outputToken`, `isBorrow` */ mapping(address => DataTypes.LiquidityPool) public creditPools; /** * @notice liquidityPool address mapped to its adapter */ mapping(address => address) public liquidityPoolToAdapter; /** * @dev riskProfileCode mapped to its struct `RiskProfile` */ mapping(uint256 => DataTypes.RiskProfile) internal riskProfiles; /** * @notice vault contract address mapped to VaultConfiguration */ mapping(address => DataTypes.VaultConfiguration) public vaultToVaultConfiguration; /** * @dev Mapping of users that are allowed to interact with a given vault */ mapping(address => mapping(address => bool)) public whitelistedUsers; /** * @notice withdrawal fee's range */ DataTypes.WithdrawalFeeRange public withdrawalFeeRange; /** * @notice List of all the tokenHashes */ bytes32[] public tokensHashIndexes; /** * @notice List of all the riskProfiles */ uint256[] public riskProfilesArray; /** * @notice strategyProvider contract address */ address public strategyProvider; /** * @notice investStrategyRegistry contract address */ address public investStrategyRegistry; /** * @notice riskManager contract address */ address public riskManager; /** * @notice harvestCodeProvider contract address */ address public harvestCodeProvider; /** * @notice strategyManager contract address */ address public strategyManager; /** * @notice opty contract address */ address public opty; /** * @notice aprOracle contract address */ address public aprOracle; /** * @notice optyStakingRateBalancer contract address */ address public optyStakingRateBalancer; /** * @notice OD vaultBooster contract address */ address public odefiVaultBooster; /** * @notice Emitted when token is approved or revoked * @param token Underlying Token's address which is approved or revoked * @param enabled Token is approved (true) or revoked (false) * @param caller Address of user who has called the respective function to trigger this event */ event LogToken(address indexed token, bool indexed enabled, address indexed caller); /** * @notice Emitted when pool is approved or revoked as liquidity pool * @param pool Liquidity Pool's address which is approved or revoked * @param enabled Liquidity Pool is approved (true) or revoked (false) * @param caller Address of user who has called the respective function to trigger this event */ event LogLiquidityPool(address indexed pool, bool indexed enabled, address indexed caller); /** * @notice Emitted when pool is approved or revoked as credit pool * @param pool Credit Pool's address which is approved or revoked * @param enabled Credit pool is approved (true) or revoked (false) * @param caller Address of user who has called the respective function to trigger this event */ event LogCreditPool(address indexed pool, bool indexed enabled, address indexed caller); /** * @notice Emitted when liquidity pool is rated * @param pool Liquidity Pool's address which is rated * @param rate Rating of Liquidity Pool set * @param caller Address of user who has called the respective function to trigger this event */ event LogRateLiquidityPool(address indexed pool, uint8 indexed rate, address indexed caller); /** * @notice Emitted when credit pool is rated * @param pool Credit Pool's address which is rated * @param rate Rating of Credit Pool set * @param caller Address of user who has called the respective function to trigger this event */ event LogRateCreditPool(address indexed pool, uint8 indexed rate, address indexed caller); /** * @notice Emitted when liquidity pool pool is assigned to adapter * @param pool Liquidity Pool's address which is mapped to the adapter * @param adapter Address of the respective OptyFi's defi-adapter contract which is mapped to the Liquidity Pool * @param caller Address of user who has called the respective function to trigger this event */ event LogLiquidityPoolToAdapter(address indexed pool, address indexed adapter, address indexed caller); /** * @notice Emitted when tokens are assigned to tokensHash * @param tokensHash Hash of the token/list of tokens mapped to the provided token/list of tokens * @param caller Address of user who has called the respective function to trigger this event */ event LogTokensToTokensHash(bytes32 indexed tokensHash, address indexed caller); /** * @dev Emitted when Discontinue over vault is activated * @param vault OptyFi's Vault contract address which is discontinued from being operational * @param discontinued Discontinue status (true) of OptyFi's Vault contract * @param caller Address of user who has called the respective function to trigger this event */ event LogDiscontinueVault(address indexed vault, bool indexed discontinued, address indexed caller); /** * @notice Emitted when Pause over vault is activated/deactivated * @param vault OptyFi's Vault contract address * @param unpaused Unpause status of OptyFi's Vault contract - false (if paused) and true (if unpaused) * @param caller Address of user who has called the respective function to trigger this event */ event LogUnpauseVault(address indexed vault, bool indexed unpaused, address indexed caller); /** * @notice Emitted when setLimitStatus is called * @param vault OptyFi's Vault contract address * @param isLimitedState Limit state of OptyFi's Vault contract - false (if not limited) and true (if limited) * @param caller Address of user who has called the respective function to trigger this event */ event LogLimitStateVault(address indexed vault, bool indexed isLimitedState, address indexed caller); /** * @notice Emitted when setLimitStatus is called * @param vault OptyFi's Vault contract address * @param allowWhitelistedState Whitelisted state of OptyFi's Vault contract - false (if not ) and true (if limited) * @param caller Address of user who has called the respective function to trigger this event */ event LogAllowWhitelistedStateVault( address indexed vault, bool indexed allowWhitelistedState, address indexed caller ); /** * @notice Emitted when setUserDepositCap is called * @param vault OptyFi's Vault contract address * @param userDepositCap Cap for user deposits in OptyFi's Vault contract * @param caller Address of user who has called the respective function to trigger this event */ event LogUserDepositCapVault(address indexed vault, uint256 indexed userDepositCap, address indexed caller); /** * @notice Emitted when setMinimumDepositAmount is called * @param vault OptyFi's Vault contract address * @param minimumDepositAmount Minimum deposit in OptyFi's Vault contract - only for deposits (without rebalance) * @param caller Address of user who has called the respective function to trigger this event */ event LogMinimumDepositAmountVault( address indexed vault, uint256 indexed minimumDepositAmount, address indexed caller ); /** * @notice Emitted when setTotalValueLockedLimitInUnderlying is called * @param vault OptyFi's Vault contract address * @param totalValueLockedLimitInUnderlying Maximum limit for total value locked of OptyFi's Vault contract * @param caller Address of user who has called the respective function to trigger this event */ event LogVaultTotalValueLockedLimitInUnderlying( address indexed vault, uint256 indexed totalValueLockedLimitInUnderlying, address indexed caller ); /** * @notice Emitted when setQueueCap is called * @param vault OptyFi's Vault contract address * @param queueCap Maximum queue length in OptyFi's Vault contract * @param caller Address of user who has called the respective function to trigger this event */ event LogQueueCapVault(address indexed vault, uint256 indexed queueCap, address indexed caller); /** * @notice Emitted when RiskProfile is added * @param index Index of an array at which risk profile is added * @param exists Status of risk profile if it exists (true) or not (false) * @param canBorrow Borrow is allowed (true) or not (false) for the specified risk profile * @param caller Address of user who has called the respective function to trigger this event */ event LogRiskProfile(uint256 indexed index, bool indexed exists, bool indexed canBorrow, address caller); /** * @notice Emitted when Risk profile is added/updated * @param index Index of an array at which risk profile is added or updated * @param lowerLimit Lower limit of the pool for the specified risk profile * @param upperLimit Upper limit of the pool for the specified risk profile * @param caller Address of user who has called the respective function to trigger this event */ event LogRPPoolRatings(uint256 indexed index, uint8 indexed lowerLimit, uint8 indexed upperLimit, address caller); } // SPDX-License-Identifier: MIT pragma solidity ^0.6.12; // libraries import { Address } from "@openzeppelin/contracts/utils/Address.sol"; // helper contracts import { RegistryStorage } from "./RegistryStorage.sol"; // interfaces import { IModifiersController } from "../../interfaces/opty/IModifiersController.sol"; /** * @title ModifiersController Contract * @author Opty.fi * @notice Contract used by registry contract and acts as source of truth * @dev It manages operator, optyDistributor addresses as well as modifiers */ abstract contract ModifiersController is IModifiersController, RegistryStorage { using Address for address; /** * @inheritdoc IModifiersController */ function setFinanceOperator(address _financeOperator) public override onlyGovernance { require(_financeOperator != address(0), "!address(0)"); financeOperator = _financeOperator; emit TransferFinanceOperator(financeOperator, msg.sender); } /** * @inheritdoc IModifiersController */ function setRiskOperator(address _riskOperator) public override onlyGovernance { require(_riskOperator != address(0), "!address(0)"); riskOperator = _riskOperator; emit TransferRiskOperator(riskOperator, msg.sender); } /** * @inheritdoc IModifiersController */ function setStrategyOperator(address _strategyOperator) public override onlyGovernance { require(_strategyOperator != address(0), "!address(0)"); strategyOperator = _strategyOperator; emit TransferStrategyOperator(strategyOperator, msg.sender); } /** * @inheritdoc IModifiersController */ function setOperator(address _operator) public override onlyGovernance { require(_operator != address(0), "!address(0)"); operator = _operator; emit TransferOperator(operator, msg.sender); } /** * @inheritdoc IModifiersController */ function setOPTYDistributor(address _optyDistributor) public override onlyGovernance { require(_optyDistributor.isContract(), "!isContract"); optyDistributor = _optyDistributor; emit TransferOPTYDistributor(optyDistributor, msg.sender); } /** * @notice Modifier to check caller is governance or not */ modifier onlyGovernance() { require(msg.sender == governance, "caller is not having governance"); _; } /** * @notice Modifier to check caller is financeOperator or not */ modifier onlyFinanceOperator() { require(msg.sender == financeOperator, "caller is not the finance operator"); _; } /** * @notice Modifier to check caller is riskOperator or not */ modifier onlyRiskOperator() { require(msg.sender == riskOperator, "caller is not the risk operator"); _; } /** * @notice Modifier to check caller is operator or not */ modifier onlyOperator() { require(msg.sender == operator, "caller is not the operator"); _; } /** * @notice Modifier to check caller is optyDistributor or not */ modifier onlyOptyDistributor() { require(msg.sender == optyDistributor, "caller is not the optyDistributor"); _; } } // SPDX-License-Identifier: MIT pragma solidity ^0.6.12; library DataTypes { /** * @notice Container for User Deposit/withdraw operations * @param account User's address * @param isDeposit True if it is deposit and false if it withdraw * @param value Amount to deposit/withdraw */ struct UserDepositOperation { address account; uint256 value; } /** * @notice Container for token balance in vault contract in a specific block * @param actualVaultValue current balance of the vault contract * @param blockMinVaultValue minimum balance recorded for vault contract in the same block * @param blockMaxVaultValue maximum balance recorded for vault contract in the same block */ struct BlockVaultValue { uint256 actualVaultValue; uint256 blockMinVaultValue; uint256 blockMaxVaultValue; } /** * @notice Container for Strategy Steps used by Strategy * @param pool Liquidity Pool address * @param outputToken Output token of the liquidity pool * @param isBorrow If borrow is allowed or not for the liquidity pool */ struct StrategyStep { address pool; address outputToken; bool isBorrow; } /** * @notice Container for pool's configuration * @param rating Rating of the liquidity pool * @param isLiquidityPool If pool is enabled as liquidity pool */ struct LiquidityPool { uint8 rating; bool isLiquidityPool; } /** * @notice Container for Strategy used by Vault contract * @param index Index at which strategy is stored * @param strategySteps StrategySteps consisting pool, outputToken and isBorrow */ struct Strategy { uint256 index; StrategyStep[] strategySteps; } /** * @notice Container for all Tokens * @param index Index at which token is stored * @param tokens List of token addresses */ struct Token { uint256 index; address[] tokens; } /** * @notice Container for pool and its rating * @param pool Address of liqudity pool * @param rate Value to be set as rate for the liquidity pool */ struct PoolRate { address pool; uint8 rate; } /** * @notice Container for mapping the liquidity pool and adapter * @param pool liquidity pool address * @param adapter adapter contract address corresponding to pool */ struct PoolAdapter { address pool; address adapter; } /** * @notice Container for having limit range for the pools * @param lowerLimit liquidity pool rate's lower limit * @param upperLimit liquidity pool rate's upper limit */ struct PoolRatingsRange { uint8 lowerLimit; uint8 upperLimit; } /** * @notice Container for having limit range for withdrawal fee * @param lowerLimit withdrawal fee's lower limit * @param upperLimit withdrawal fee's upper limit */ struct WithdrawalFeeRange { uint256 lowerLimit; uint256 upperLimit; } /** * @notice Container for containing risk Profile's configuration * @param index Index at which risk profile is stored * @param canBorrow True if borrow is allowed for the risk profile * @param poolRatingsRange Container for having limit range for the pools * @param exists if risk profile exists or not */ struct RiskProfile { uint256 index; bool canBorrow; PoolRatingsRange poolRatingsRange; bool exists; string name; string symbol; } /** * @notice Container for holding percentage of reward token to hold and convert * @param hold reward token hold percentage in basis point * @param convert reward token convert percentage in basis point */ struct VaultRewardStrategy { uint256 hold; // should be in basis eg: 50% means 5000 uint256 convert; // should be in basis eg: 50% means 5000 } /** @notice Named Constants for defining max exposure state */ enum MaxExposure { Number, Pct } /** @notice Named Constants for defining default strategy state */ enum DefaultStrategyState { Zero, CompoundOrAave } /** * @notice Container for persisting ODEFI contract's state * @param index The market's last index * @param timestamp The block number the index was last updated at */ struct RewardsState { uint224 index; uint32 timestamp; } /** * @notice Container for Treasury accounts along with their shares * @param treasury treasury account address * @param share treasury's share in percentage from the withdrawal fee */ struct TreasuryShare { address treasury; uint256 share; // should be in basis eg: 5% means 500 } /** * @notice Container for combining Vault contract's configuration * @param discontinued If the vault contract is discontinued or not * @param unpaused If the vault contract is paused or unpaused * @param withdrawalFee withdrawal fee for a particular vault contract * @param treasuryShares Treasury accounts along with their shares * @param isLimitedState If the vault contract has a limit for total user deposits * @param allowWhitelistedState If the vault contract require whitelisted users or not * @param userDepositCap Maximum total amount that can be deposited by an address * @param minimumDepositAmount Minimum deposit without rebalance allowed * @param totalValueLockedLimitInUnderlying Maximum TVL in underlying allowed for the vault * @param queueCap Maximum length of the deposits without rebalance queue */ struct VaultConfiguration { bool discontinued; bool unpaused; bool isLimitedState; bool allowWhitelistedState; TreasuryShare[] treasuryShares; uint256 withdrawalFee; // should be in basis eg: 15% means 1500 uint256 userDepositCap; uint256 minimumDepositAmount; uint256 totalValueLockedLimitInUnderlying; uint256 queueCap; } /** * @notice Container for persisting all strategy related contract's configuration * @param investStrategyRegistry investStrategyRegistry contract address * @param strategyProvider strategyProvider contract address * @param aprOracle aprOracle contract address */ struct StrategyConfiguration { address investStrategyRegistry; address strategyProvider; address aprOracle; } /** * @notice Container for persisting contract addresses required by vault contract * @param strategyManager strategyManager contract address * @param riskManager riskManager contract address * @param optyDistributor optyDistributor contract address * @param operator operator contract address */ struct VaultStrategyConfiguration { address strategyManager; address riskManager; address optyDistributor; address odefiVaultBooster; address operator; } } // 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.12; /** * @title Interface for ModifiersController Contract * @author Opty.fi * @notice Interface used to authorize operator and minter accounts */ interface IModifiersController { /** * @notice Transfers financeOperator to a new account (`_financeOperator`) * @param _financeOperator address of financeOperator's account */ function setFinanceOperator(address _financeOperator) external; /** * @notice Transfers riskOperator to a new account (`_riskOperator`) * @param _riskOperator address of riskOperator's account */ function setRiskOperator(address _riskOperator) external; /** * @notice Transfers strategyOperator to a new account (`_strategyOperator`) * @param _strategyOperator address of strategyOperator's account */ function setStrategyOperator(address _strategyOperator) external; /** * @notice Transfers operator to a new account (`_operator`) * @param _operator address of Operator's account */ function setOperator(address _operator) external; /** * @notice Transfers optyDistributor to a new account (`_optyDistributor`) * @param _optyDistributor address of optyDistributor contract */ function setOPTYDistributor(address _optyDistributor) external; }