Address Contract Partially Verified
Address
0xFa68707be4b58FB9F10748E30e25A15113EdEE1D
Balance
0 ETH
Nonce
1
Code Size
4658 bytes
Creator
0x2532C3D3...8154 at tx 0x001a2122...99f422
Proxy
EIP-1967 Proxy Implementation: 0xDFC8cD9F...4ff2
Indexed Transactions
0
Contract Bytecode
4658 bytes
0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063734daaa1116100a2578063bfbdc77211610071578063bfbdc772146102af578063d19a3bb8146102b7578063d8dfeb45146102d2578063f384bd05146102da578063fde813a8146102e257610116565b8063734daaa1146102235780637a2b4f811461024a5780639d7fb70c1461025d578063a8aa1b311461027057610116565b806342c5ddc4116100e957806342c5ddc4146101b057806346aa2f12146101bd57806349317f1d146101d2578063503160d9146101da5780635d265d3f146101ed57610116565b806304bd4629146101515780631e957a23146101775780632ee9f969146101805780633d6cb5751461019d575b73dfc8cd9f2f2d306b7c0d109f005df661e14f4ff23660008037600080366000845af43d6000803e80801561014a573d6000f35b3d6000fd5b005b61016461015f366004610f40565b6102f5565b6040519081526020015b60405180910390f35b61016460015481565b60025461018d9060ff1681565b604051901515815260200161016e565b61014f6101ab366004610f5d565b6104c3565b60005461018d9060ff1681565b6101646101cb366004610f40565b5060001990565b6101646104d7565b61014f6101e8366004610f5d565b6104ee565b60408051600481526024810182526020810180516001600160e01b031663440368a360e01b179052905161016e91600091610f76565b6101647f000000000000000000000000000000000000000000000000000000000000000081565b61014f610258366004610f5d565b6104ff565b61014f61026b366004610f5d565b6105d3565b6102977f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e81565b6040516001600160a01b03909116815260200161016e565b61014f6105db565b61029773dfc8cd9f2f2d306b7c0d109f005df661e14f4ff281565b610297610673565b6101646106f7565b61014f6102f0366004610f5d565b61077b565b6000600154421061043c576040516370a0823160e01b81526001600160a01b037f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e811660048301527f00000000000000000000000004c154b66cb340f3ae24111cc767e0184ed00cc616906370a0823190602401602060405180830381865afa158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103aa9190610fce565b7f000000000000000000000000fa68707be4b58fb9f10748e30e25a15113edee1d6001600160a01b0316639aa7df946040518163ffffffff1660e01b8152600401602060405180830381865afa158015610408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042c9190610fce565b6104369190610fe7565b92915050565b7f000000000000000000000000fa68707be4b58fb9f10748e30e25a15113edee1d6001600160a01b0316639aa7df946040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104369190610fce565b919050565b6104cb61078c565b6104d4816107c5565b50565b60006104e161078c565b6104e96109a5565b905090565b6104f661078c565b6104d481610bca565b604051631d818fc560e31b81523360048201527f000000000000000000000000fa68707be4b58fb9f10748e30e25a15113edee1d6001600160a01b03169063ec0c7e2890602401602060405180830381865afa158015610563573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105879190611008565b5060025460ff16156105ce5760405162461bcd60e51b815260206004820152600b60248201526a3637b1b590333937bd32b760a91b60448201526064015b60405180910390fd5b600155565b6104d461078c565b604051631d818fc560e31b81523360048201527f000000000000000000000000fa68707be4b58fb9f10748e30e25a15113edee1d6001600160a01b03169063ec0c7e2890602401602060405180830381865afa15801561063f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106639190611008565b506002805460ff19166001179055565b60007f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b031663c6e1c7c96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e9919061102a565b60007f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b031663f384bd056040518163ffffffff1660e01b8152600401602060405180830381865afa158015610757573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190610fce565b61078361078c565b6104d481610cb0565b3330146107c35760405162461bcd60e51b815260206004820152600560248201526410b9b2b63360d91b60448201526064016105c5565b565b600154421061097357604051631c6c959760e01b8152600060048201527f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b031690631c6c959790602401610180604051808303816000875af1158015610836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085a9190611136565b5050604051631c2591d360e01b81526004810186905260006024820181905260448201527f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b0316945063ba0876529350849250631c2591d39150606401602060405180830381865afa1580156108db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ff9190610fce565b6040516001600160e01b031960e084901b1681526004810191909152306024820181905260448201526064015b6020604051808303816000875af115801561094b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096f9190610fce565b5050565b60405162461bcd60e51b81526020600482015260076024820152664c6f636b65642160c81b60448201526064016105c5565b604051631c6c959760e01b8152600060048201819052907f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b031690631c6c959790602401610180604051808303816000875af1158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190611136565b50506040516370a0823160e01b81523060048201527f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b03169450637d37bdd793508492506370a082319150602401602060405180830381865afa158015610aa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aca9190610fce565b6040516001600160e01b031960e084901b16815260048101919091526000602482018190526044820152606401602060405180830381865afa158015610b14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b389190610fce565b6040516370a0823160e01b81523060048201527f00000000000000000000000004c154b66cb340f3ae24111cc767e0184ed00cc66001600160a01b0316906370a0823190602401602060405180830381865afa158015610b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190610fce565b6104e99190610fe7565b60005460ff1615610c2857604051636e553f6560e01b8152600481018290523060248201527f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b031690636e553f659060440161092c565b7f00000000000000000000000000000000000000000000000000000000000000008111156104d4576000805460ff19166001179055604051636e553f6560e01b8152600481018290523060248201526001600160a01b037f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e1690636e553f659060440161092c565b604051631c6c959760e01b8152600060048201527f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b031690631c6c959790602401610180604051808303816000875af1158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190611136565b5050604051631c2591d360e01b8152600481018690526001602482015260006044820181905294507f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b03169350631c2591d392506064019050602060405180830381865afa158015610db9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ddd9190610fce565b6040516370a0823160e01b8152306004820152909150610e739082906001600160a01b037f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e16906370a0823190602401602060405180830381865afa158015610e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e9190610fce565b610f13565b604051635d043b2960e11b815260048101829052306024820181905260448201529091507f00000000000000000000000035b5564a1e7b3a90d8e9f0e9ea246ca68842393e6001600160a01b03169063ba087652906064016020604051808303816000875af1158015610eea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0e9190610fce565b505050565b6000818310610f225781610f24565b825b9392505050565b6001600160a01b03811681146104d457600080fd5b600060208284031215610f5257600080fd5b8135610f2481610f2b565b600060208284031215610f6f57600080fd5b5035919050565b821515815260006020604081840152835180604085015260005b81811015610fac57858101830151858201606001528201610f90565b506000606082860101526060601f19601f830116850101925050509392505050565b600060208284031215610fe057600080fd5b5051919050565b8082018082111561043657634e487b7160e01b600052601160045260246000fd5b60006020828403121561101a57600080fd5b81518015158114610f2457600080fd5b60006020828403121561103c57600080fd5b8151610f2481610f2b565b60405160a0810167ffffffffffffffff8111828210171561107857634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff811681146104be57600080fd5b805167ffffffffffffffff811681146104be57600080fd5b80516fffffffffffffffffffffffffffffffff811681146104be57600080fd5b6000604082840312156110dc57600080fd5b6040516040810181811067ffffffffffffffff8211171561110d57634e487b7160e01b600052604160045260246000fd5b60405290508061111c836110aa565b815261112a602084016110aa565b60208201525092915050565b60008060008060008086880361018081121561115157600080fd5b87519650602088015195506040880151945060a0605f198201121561117557600080fd5b5061117e611047565b61118a6060890161107e565b81526111986080890161107e565b60208201526111a960a08901611092565b60408201526111ba60c08901611092565b60608201526111cb60e08901611092565b608082015292506111e08861010089016110ca565b91506111f08861014089016110ca565b9050929550929550929556fea2646970667358221220e2a5a566ea94379bc46670a3020497615da8004810c34efaad805971d40b37cf64736f6c63430008150033
Verified Source Code Partial Match
Compiler: v0.8.21+commit.d9974bed
EVM: paris
Optimization: Yes (200 runs)
SturdySiloStrategy.sol 2567 lines
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.21;
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
interface ITokenizedStrategy is IERC4626, IERC20Permit {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UpdatePendingManagement(address indexed newPendingManagement);
event UpdateManagement(address indexed newManagement);
event UpdateKeeper(address indexed newKeeper);
event UpdateEmergencyAdmin(address indexed newEmergencyAdmin);
event UpdatePerformanceFee(uint16 newPerformanceFee);
event UpdatePerformanceFeeRecipient(
address indexed newPerformanceFeeRecipient
);
event UpdateProfitMaxUnlockTime(uint256 newProfitMaxUnlockTime);
event StrategyShutdown();
event Reported(
uint256 profit,
uint256 loss,
uint256 protocolFees,
uint256 performanceFees
);
/*//////////////////////////////////////////////////////////////
INITIALIZATION
//////////////////////////////////////////////////////////////*/
function init(
address _asset,
string memory _name,
address _management,
address _performanceFeeRecipient,
address _keeper
) external;
/*//////////////////////////////////////////////////////////////
NON-STANDARD 4626 OPTIONS
//////////////////////////////////////////////////////////////*/
function withdraw(
uint256 assets,
address receiver,
address owner,
uint256 maxLoss
) external returns (uint256);
function redeem(
uint256 shares,
address receiver,
address owner,
uint256 maxLoss
) external returns (uint256);
/*//////////////////////////////////////////////////////////////
MODIFIERS
//////////////////////////////////////////////////////////////*/
function isManagement(address _sender) external view returns (bool);
function isKeeperOrManagement(address _sender) external view returns (bool);
function isEmergencyAuthorized(
address _sender
) external view returns (bool);
/*//////////////////////////////////////////////////////////////
KEEPERS FUNCTIONS
//////////////////////////////////////////////////////////////*/
function tend() external;
function report() external returns (uint256 _profit, uint256 _loss);
/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
function MIN_FEE() external view returns (uint16);
function MAX_FEE() external view returns (uint16);
function FACTORY() external view returns (address);
/*//////////////////////////////////////////////////////////////
GETTERS
//////////////////////////////////////////////////////////////*/
function apiVersion() external view returns (string memory);
function pricePerShare() external view returns (uint256);
function totalIdle() external view returns (uint256);
function totalDebt() external view returns (uint256);
function management() external view returns (address);
function pendingManagement() external view returns (address);
function keeper() external view returns (address);
function emergencyAdmin() external view returns (address);
function performanceFee() external view returns (uint16);
function performanceFeeRecipient() external view returns (address);
function fullProfitUnlockDate() external view returns (uint256);
function profitUnlockingRate() external view returns (uint256);
function profitMaxUnlockTime() external view returns (uint256);
function lastReport() external view returns (uint256);
function isShutdown() external view returns (bool);
function unlockedShares() external view returns (uint256);
/*//////////////////////////////////////////////////////////////
SETTERS
//////////////////////////////////////////////////////////////*/
function setPendingManagement(address) external;
function acceptManagement() external;
function setKeeper(address _keeper) external;
function setEmergencyAdmin(address _emergencyAdmin) external;
function setPerformanceFee(uint16 _performanceFee) external;
function setPerformanceFeeRecipient(
address _performanceFeeRecipient
) external;
function setProfitMaxUnlockTime(uint256 _profitMaxUnlockTime) external;
function shutdownStrategy() external;
function emergencyWithdraw(uint256 _amount) external;
/*//////////////////////////////////////////////////////////////
ERC20 ADD ONS
//////////////////////////////////////////////////////////////*/
function decreaseAllowance(
address spender,
uint256 subtractedValue
) external returns (bool);
function increaseAllowance(
address spender,
uint256 addedValue
) external returns (bool);
}
abstract contract BaseStrategy {
/*//////////////////////////////////////////////////////////////
MODIFIERS
//////////////////////////////////////////////////////////////*/
/**
* @dev Used on TokenizedStrategy callback functions to make sure it is post
* a delegateCall from this address to the TokenizedStrategy.
*/
modifier onlySelf() {
_onlySelf();
_;
}
/**
* @dev Use to assure that the call is coming from the strategies management.
*/
modifier onlyManagement() {
TokenizedStrategy.isManagement(msg.sender);
_;
}
/**
* @dev Use to assure that the call is coming from either the strategies
* management or the keeper.
*/
modifier onlyKeepers() {
TokenizedStrategy.isKeeperOrManagement(msg.sender);
_;
}
/**
* @dev Use to assure that the call is coming from either the strategies
* management or the emergency admin.
*/
modifier onlyEmergencyAuthorized() {
TokenizedStrategy.isEmergencyAuthorized(msg.sender);
_;
}
function _onlySelf() internal view {
require(msg.sender == address(this), "!self");
}
/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
/**
* This is the address of the TokenizedStrategy implementation
* contract that will be used by all strategies to handle the
* accounting, logic, storage etc.
*
* Any external calls to the that don't hit one of the functions
* defined in this base or the strategy will end up being forwarded
* through the fallback function, which will delegateCall this address.
*
* This address should be the same for every strategy, never be adjusted
* and always be checked before any integration with the Strategy.
*/
address public constant tokenizedStrategyAddress =
0xDFC8cD9F2f2d306b7C0d109F005DF661E14f4ff2;
/*//////////////////////////////////////////////////////////////
IMMUTABLES
//////////////////////////////////////////////////////////////*/
/**
* This variable is set to address(this) during initialization of each strategy.
*
* This can be used to retrieve storage data within the strategy
* contract as if it were a linked library.
*
* i.e. uint256 totalAssets = TokenizedStrategy.totalAssets()
*
* Using address(this) will mean any calls using this variable will lead
* to a call to itself. Which will hit the fallback function and
* delegateCall that to the actual TokenizedStrategy.
*/
ITokenizedStrategy internal immutable TokenizedStrategy;
// Underlying asset the Strategy is earning yield on.
// Stored here for cheap retrievals within the strategy.
ERC20 internal immutable asset;
/**
* @notice Used to initialize the strategy on deployment.
*
* This will set the `TokenizedStrategy` variable for easy
* internal view calls to the implementation. As well as
* initializing the default storage variables based on the
* parameters and using the deployer for the permissioned roles.
*
* @param _asset Address of the underlying asset.
* @param _name Name the strategy will use.
*/
constructor(address _asset, string memory _name) {
asset = ERC20(_asset);
// Set instance of the implementation for internal use.
TokenizedStrategy = ITokenizedStrategy(address(this));
// Initialize the strategy's storage variables.
_delegateCall(
abi.encodeCall(
ITokenizedStrategy.init,
(_asset, _name, msg.sender, msg.sender, msg.sender)
)
);
// Store the tokenizedStrategyAddress at the standard implementation
// address storage slot so etherscan picks up the interface. This gets
// stored on initialization and never updated.
assembly {
sstore(
// keccak256('eip1967.proxy.implementation' - 1)
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,
tokenizedStrategyAddress
)
}
}
/*//////////////////////////////////////////////////////////////
NEEDED TO BE OVERRIDDEN BY STRATEGIST
//////////////////////////////////////////////////////////////*/
/**
* @dev Should deploy up to '_amount' of 'asset' in the yield source.
*
* This function is called at the end of a {deposit} or {mint}
* call. Meaning that unless a whitelist is implemented it will
* be entirely permissionless and thus can be sandwiched or otherwise
* manipulated.
*
* @param _amount The amount of 'asset' that the strategy should attempt
* to deposit in the yield source.
*/
function _deployFunds(uint256 _amount) internal virtual;
/**
* @dev Will attempt to free the '_amount' of 'asset'.
*
* The amount of 'asset' that is already loose has already
* been accounted for.
*
* This function is called during {withdraw} and {redeem} calls.
* Meaning that unless a whitelist is implemented it will be
* entirely permissionless and thus can be sandwiched or otherwise
* manipulated.
*
* Should not rely on asset.balanceOf(address(this)) calls other than
* for diff accounting purposes.
*
* Any difference between `_amount` and what is actually freed will be
* counted as a loss and passed on to the withdrawer. This means
* care should be taken in times of illiquidity. It may be better to revert
* if withdraws are simply illiquid so not to realize incorrect losses.
*
* @param _amount, The amount of 'asset' to be freed.
*/
function _freeFunds(uint256 _amount) internal virtual;
/**
* @dev Internal function to harvest all rewards, redeploy any idle
* funds and return an accurate accounting of all funds currently
* held by the Strategy.
*
* This should do any needed harvesting, rewards selling, accrual,
* redepositing etc. to get the most accurate view of current assets.
*
* NOTE: All applicable assets including loose assets should be
* accounted for in this function.
*
* Care should be taken when relying on oracles or swap values rather
* than actual amounts as all Strategy profit/loss accounting will
* be done based on this returned value.
*
* This can still be called post a shutdown, a strategist can check
* `TokenizedStrategy.isShutdown()` to decide if funds should be
* redeployed or simply realize any profits/losses.
*
* @return _totalAssets A trusted and accurate account for the total
* amount of 'asset' the strategy currently holds including idle funds.
*/
function _harvestAndReport()
internal
virtual
returns (uint256 _totalAssets);
/*//////////////////////////////////////////////////////////////
OPTIONAL TO OVERRIDE BY STRATEGIST
//////////////////////////////////////////////////////////////*/
/**
* @dev Optional function for strategist to override that can
* be called in between reports.
*
* If '_tend' is used tendTrigger() will also need to be overridden.
*
* This call can only be called by a permissioned role so may be
* through protected relays.
*
* This can be used to harvest and compound rewards, deposit idle funds,
* perform needed position maintenance or anything else that doesn't need
* a full report for.
*
* EX: A strategy that can not deposit funds without getting
* sandwiched can use the tend when a certain threshold
* of idle to totalAssets has been reached.
*
* The TokenizedStrategy contract will do all needed debt and idle updates
* after this has finished and will have no effect on PPS of the strategy
* till report() is called.
*
* @param _totalIdle The current amount of idle funds that are available to deploy.
*/
function _tend(uint256 _totalIdle) internal virtual {}
/**
* @dev Optional trigger to override if tend() will be used by the strategy.
* This must be implemented if the strategy hopes to invoke _tend().
*
* @return . Should return true if tend() should be called by keeper or false if not.
*/
function _tendTrigger() internal view virtual returns (bool) {
return false;
}
/**
* @notice Returns if tend() should be called by a keeper.
*
* @return . Should return true if tend() should be called by keeper or false if not.
* @return . Calldata for the tend call.
*/
function tendTrigger() external view virtual returns (bool, bytes memory) {
return (
// Return the status of the tend trigger.
_tendTrigger(),
// And the needed calldata either way.
abi.encodeWithSelector(ITokenizedStrategy.tend.selector)
);
}
/**
* @notice Gets the max amount of `asset` that an address can deposit.
* @dev Defaults to an unlimited amount for any address. But can
* be overridden by strategists.
*
* This function will be called before any deposit or mints to enforce
* any limits desired by the strategist. This can be used for either a
* traditional deposit limit or for implementing a whitelist etc.
*
* EX:
* if(isAllowed[_owner]) return super.availableDepositLimit(_owner);
*
* This does not need to take into account any conversion rates
* from shares to assets. But should know that any non max uint256
* amounts may be converted to shares. So it is recommended to keep
* custom amounts low enough as not to cause overflow when multiplied
* by `totalSupply`.
*
* @param . The address that is depositing into the strategy.
* @return . The available amount the `_owner` can deposit in terms of `asset`
*/
function availableDepositLimit(
address /*_owner*/
) public view virtual returns (uint256) {
return type(uint256).max;
}
/**
* @notice Gets the max amount of `asset` that can be withdrawn.
* @dev Defaults to an unlimited amount for any address. But can
* be overridden by strategists.
*
* This function will be called before any withdraw or redeem to enforce
* any limits desired by the strategist. This can be used for illiquid
* or sandwichable strategies. It should never be lower than `totalIdle`.
*
* EX:
* return TokenIzedStrategy.totalIdle();
*
* This does not need to take into account the `_owner`'s share balance
* or conversion rates from shares to assets.
*
* @param . The address that is withdrawing from the strategy.
* @return . The available amount that can be withdrawn in terms of `asset`
*/
function availableWithdrawLimit(
address /*_owner*/
) public view virtual returns (uint256) {
return type(uint256).max;
}
/**
* @dev Optional function for a strategist to override that will
* allow management to manually withdraw deployed funds from the
* yield source if a strategy is shutdown.
*
* This should attempt to free `_amount`, noting that `_amount` may
* be more than is currently deployed.
*
* NOTE: This will not realize any profits or losses. A separate
* {report} will be needed in order to record any profit/loss. If
* a report may need to be called after a shutdown it is important
* to check if the strategy is shutdown during {_harvestAndReport}
* so that it does not simply re-deploy all funds that had been freed.
*
* EX:
* if(freeAsset > 0 && !TokenizedStrategy.isShutdown()) {
* depositFunds...
* }
*
* @param _amount The amount of asset to attempt to free.
*/
function _emergencyWithdraw(uint256 _amount) internal virtual {}
/*//////////////////////////////////////////////////////////////
TokenizedStrategy HOOKS
//////////////////////////////////////////////////////////////*/
/**
* @notice Should deploy up to '_amount' of 'asset' in yield source.
* @dev Callback for the TokenizedStrategy to call during a {deposit}
* or {mint} to tell the strategy it can deploy funds.
*
* Since this can only be called after a {deposit} or {mint}
* delegateCall to the TokenizedStrategy msg.sender == address(this).
*
* Unless a whitelist is implemented this will be entirely permissionless
* and thus can be sandwiched or otherwise manipulated.
*
* @param _amount The amount of 'asset' that the strategy should
* attempt to deposit in the yield source.
*/
function deployFunds(uint256 _amount) external virtual onlySelf {
_deployFunds(_amount);
}
/**
* @notice Will attempt to free the '_amount' of 'asset'.
* @dev Callback for the TokenizedStrategy to call during a withdraw
* or redeem to free the needed funds to service the withdraw.
*
* This can only be called after a 'withdraw' or 'redeem' delegateCall
* to the TokenizedStrategy so msg.sender == address(this).
*
* @param _amount The amount of 'asset' that the strategy should attempt to free up.
*/
function freeFunds(uint256 _amount) external virtual onlySelf {
_freeFunds(_amount);
}
/**
* @notice Returns the accurate amount of all funds currently
* held by the Strategy.
* @dev Callback for the TokenizedStrategy to call during a report to
* get an accurate accounting of assets the strategy controls.
*
* This can only be called after a report() delegateCall to the
* TokenizedStrategy so msg.sender ...
// [truncated — 100796 bytes total]
Read Contract
availableDepositLimit 0x46aa2f12 → uint256
availableWithdrawLimit 0x04bd4629 → uint256
collateral 0xd8dfeb45 → address
depositThreshold 0x734daaa1 → uint256
freezeTimeToUnlock 0x2ee9f969 → bool
maxLTV 0xf384bd05 → uint256
pair 0xa8aa1b31 → address
tendTrigger 0x5d265d3f → bool, bytes
thresholdMet 0x42c5ddc4 → bool
timeToUnlock 0x1e957a23 → uint256
tokenizedStrategyAddress 0xd19a3bb8 → address
Write Contract 7 functions
These functions modify contract state and require a wallet transaction to execute.
deployFunds 0x503160d9
uint256 _amount
freeFunds 0x3d6cb575
uint256 _amount
freezeUnlock 0xbfbdc772
No parameters
harvestAndReport 0x49317f1d
No parameters
returns: uint256
setTimeToUnlock 0x7a2b4f81
uint256 _newTime
shutdownWithdraw 0xfde813a8
uint256 _amount
tendThis 0x9d7fb70c
uint256 _totalIdle
Recent Transactions
No transactions found for this address