Skip to content

Commit

Permalink
Refactor to separate vault token from vault
Browse files Browse the repository at this point in the history
  • Loading branch information
transferAndCall committed Oct 10, 2021
1 parent cd43102 commit 0c2298c
Show file tree
Hide file tree
Showing 18 changed files with 250 additions and 318 deletions.
56 changes: 12 additions & 44 deletions contracts/v3/Manager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,12 @@ contract Manager is IManager {
mapping(address => bool) public override allowedControllers;
mapping(address => bool) public override allowedConverters;
mapping(address => bool) public override allowedStrategies;
mapping(address => bool) public override allowedTokens;
mapping(address => bool) public override allowedVaults;

// vault => controller
mapping(address => address) public override controllers;
// vault => token
mapping(address => address) internal tokens;
// token => vault
mapping(address => address) public override vaults;

event AllowedController(
address indexed _controller,
Expand All @@ -78,10 +75,6 @@ contract Manager is IManager {
address indexed _strategy,
bool _allowed
);
event AllowedToken(
address indexed _token,
bool _allowed
);
event AllowedVault(
address indexed _vault,
bool _allowed
Expand All @@ -100,13 +93,12 @@ contract Manager is IManager {
event SetStrategist(
address indexed _strategist
);
event TokenAdded(
event VaultAdded(
address indexed _vault,
address indexed _token
);
event TokenRemoved(
address indexed _vault,
address indexed _token
event VaultRemoved(
address indexed _vault
);

/**
Expand Down Expand Up @@ -186,23 +178,6 @@ contract Manager is IManager {
emit AllowedStrategy(_strategy, _allowed);
}

/**
* @notice Sets the permission for the given token
* @param _token The address of the token
* @param _allowed The status of if it is allowed
*/
function setAllowedToken(
address _token,
bool _allowed
)
external
notHalted
onlyGovernance
{
allowedTokens[_token] = _allowed;
emit AllowedToken(_token, _allowed);
}

/**
* @notice Sets the permission for the given vault
* @param _vault The address of the vault
Expand Down Expand Up @@ -416,24 +391,20 @@ contract Manager is IManager {
/**
* @notice Adds a token to be able to be deposited for a given vault
* @param _vault The address of the vault
* @param _token The address of the token
*/
function addToken(
address _vault,
address _token
function addVault(
address _vault
)
external
override
notHalted
onlyStrategist
{
require(allowedTokens[_token], "!allowedTokens");
require(allowedVaults[_vault], "!allowedVaults");
require(tokens[_vault] == address(0), "!_vault");
require(vaults[_token] == address(0), "!_token");
vaults[_token] = _vault;
address _token = IVault(_vault).getToken();
tokens[_vault] = _token;
emit TokenAdded(_vault, _token);
emit VaultAdded(_vault, _token);
}

/**
Expand All @@ -458,22 +429,19 @@ contract Manager is IManager {
/**
* @notice Removes a token from being able to be deposited for a given vault
* @param _vault The address of the vault
* @param _token The address of the token
*/
function removeToken(
address _vault,
address _token
function removeVault(
address _vault
)
external
override
notHalted
onlyStrategist
{
require(tokens[_vault] == _token, "!_token");
require(vaults[_token] == _vault, "!_vault");
require(tokens[_vault] != address(0), "!_vault");
delete tokens[_vault];
delete vaults[_token];
emit TokenRemoved(_vault, _token);
delete allowedVaults[_vault];
emit VaultRemoved(_vault);
}

/**
Expand Down
102 changes: 52 additions & 50 deletions contracts/v3/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,28 @@ import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/GSN/Context.sol";

import "./VaultToken.sol";

import "./interfaces/IManager.sol";
import "./interfaces/IController.sol";
import "./interfaces/IConverter.sol";
import "./interfaces/IVault.sol";
import "./interfaces/IVaultToken.sol";
import "./interfaces/ExtendedIERC20.sol";

/**
* @title Vault
* @notice The vault is where users deposit and withdraw
* like-kind assets that have been added by governance.
*/
contract Vault is VaultToken, IVault {
contract Vault is IVault {
using Address for address;
using SafeMath for uint256;
using SafeERC20 for IERC20;

uint256 public constant MAX = 10000;

IManager public immutable override manager;
IERC20 public immutable token;
IVaultToken public immutable vaultToken;

// Strategist-updated variables
address public override gauge;
Expand All @@ -40,19 +41,20 @@ contract Vault is VaultToken, IVault {
event Earn(address indexed token, uint256 amount);

/**
* @param _name The name of the vault token for depositors
* @param _symbol The symbol of the vault token for depositors
* @param _depositToken The address of the deposit token of the vault
* @param _vaultToken The address of the share token for the vault
* @param _manager The address of the vault manager contract
*/
constructor(
string memory _name,
string memory _symbol,
address _depositToken,
address _vaultToken,
address _manager
)
public
VaultToken(_name, _symbol)
{
manager = IManager(_manager);
token = IERC20(_depositToken);
vaultToken = IVaultToken(_vaultToken);
min = 9500;
totalDepositCap = 10000000 ether;
}
Expand Down Expand Up @@ -124,13 +126,12 @@ contract Vault is VaultToken, IVault {
onlyHarvester
{
require(manager.allowedStrategies(_strategy), "!_strategy");
address _token = getToken();
IController _controller = IController(manager.controllers(address(this)));
if (_controller.investEnabled()) {
uint256 _balance = available(_token);
IERC20(_token).safeTransfer(address(_controller), _balance);
_controller.earn(_strategy, _token, _balance);
emit Earn(_token, _balance);
uint256 _balance = available();
token.safeTransfer(address(_controller), _balance);
_controller.earn(_strategy, address(token), _balance);
emit Earn(address(token), _balance);
}
}

Expand All @@ -151,29 +152,26 @@ contract Vault is VaultToken, IVault {
returns (uint256 _shares)
{
require(_amount > 0, "!_amount");
address _token = getToken();

uint256 _balance = balance();

uint256 _before = IERC20(_token).balanceOf(address(this));
IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
_amount = IERC20(_token).balanceOf(address(this)).sub(_before);

if (_amount > 0) {
_amount = _normalizeDecimals(_token, _amount);
uint256 _before = token.balanceOf(address(this));
token.safeTransferFrom(msg.sender, address(this), _amount);
_amount = token.balanceOf(address(this)).sub(_before);
uint256 _supply = IERC20(address(vaultToken)).totalSupply();

if (totalSupply() > 0) {
_amount = (_amount.mul(totalSupply())).div(_balance);
}
_amount = _normalizeDecimals(_amount);

_shares = _amount;
if (_supply > 0) {
_amount = (_amount.mul(_supply)).div(_balance);
}

if (_shares > 0) {
_mint(msg.sender, _shares);
require(totalSupply() <= totalDepositCap, ">totalDepositCap");
emit Deposit(msg.sender, _shares);
}
_shares = _amount;

require(_shares > 0, "shares=0");
require(_supply.add(_shares) <= totalDepositCap, ">totalDepositCap");
vaultToken.mint(msg.sender, _shares);
emit Deposit(msg.sender, _shares);
}

/**
Expand All @@ -186,31 +184,30 @@ contract Vault is VaultToken, IVault {
public
override
{
address _output = getToken();
uint256 _amount = (balance().mul(_shares)).div(totalSupply());
_burn(msg.sender, _shares);
uint256 _amount = (balance().mul(_shares)).div(IERC20(address(vaultToken)).totalSupply());
vaultToken.burn(msg.sender, _shares);

uint256 _withdrawalProtectionFee = manager.withdrawalProtectionFee();
if (_withdrawalProtectionFee > 0) {
uint256 _withdrawalProtection = _amount.mul(_withdrawalProtectionFee).div(MAX);
_amount = _amount.sub(_withdrawalProtection);
}

uint256 _balance = IERC20(_output).balanceOf(address(this));
uint256 _balance = token.balanceOf(address(this));
if (_balance < _amount) {
IController _controller = IController(manager.controllers(address(this)));
uint256 _toWithdraw = _amount.sub(_balance);
if (_controller.strategies() > 0) {
_controller.withdraw(_output, _toWithdraw);
_controller.withdraw(address(token), _toWithdraw);
}
uint256 _after = IERC20(_output).balanceOf(address(this));
uint256 _after = token.balanceOf(address(this));
uint256 _diff = _after.sub(_balance);
if (_diff < _toWithdraw) {
_amount = _after;
}
}

IERC20(_output).safeTransfer(msg.sender, _amount);
token.safeTransfer(msg.sender, _amount);
emit Withdraw(msg.sender, _amount);
}

Expand All @@ -221,7 +218,7 @@ contract Vault is VaultToken, IVault {
external
override
{
withdraw(balanceOf(msg.sender));
withdraw(IERC20(address(vaultToken)).balanceOf(msg.sender));
}

/**
Expand All @@ -232,17 +229,14 @@ contract Vault is VaultToken, IVault {
* @notice Returns the amount of tokens available to be sent to strategies
* @dev Custom logic in here for how much the vault allows to be borrowed
* @dev Sets minimum required on-hand to keep small withdrawals cheap
* @param _token The address of the token
*/
function available(
address _token
)
function available()
public
view
override
returns (uint256)
{
return IERC20(_token).balanceOf(address(this)).mul(min).div(MAX);
return token.balanceOf(address(this)).mul(min).div(MAX);
}

/**
Expand All @@ -265,8 +259,7 @@ contract Vault is VaultToken, IVault {
view
returns (uint256)
{
address _token = getToken();
return _normalizeDecimals(_token, IERC20(_token).balanceOf(address(this)));
return _normalizeDecimals(token.balanceOf(address(this)));
}

/**
Expand All @@ -278,23 +271,33 @@ contract Vault is VaultToken, IVault {
override
returns (uint256)
{
if (totalSupply() > 0) {
return balance().mul(1e18).div(totalSupply());
uint256 _supply = IERC20(address(vaultToken)).totalSupply();
if (_supply > 0) {
return balance().mul(1e18).div(_supply);
} else {
return balance();
}
}

/**
* @notice Returns an array of the tokens for this vault
* @notice Returns the deposit token for the vault
*/
function getToken()
public
view
override
returns (address)
{
return manager.getToken(address(this));
return address(token);
}

function getLPToken()
external
view
override
returns (address)
{
return address(vaultToken);
}

/**
Expand All @@ -313,14 +316,13 @@ contract Vault is VaultToken, IVault {
}

function _normalizeDecimals(
address _token,
uint256 _amount
)
internal
view
returns (uint256)
{
uint256 _decimals = uint256(ExtendedIERC20(_token).decimals());
uint256 _decimals = uint256(ExtendedIERC20(address(token)).decimals());
if (_decimals < 18) {
_amount = _amount.mul(10**(18-_decimals));
}
Expand Down
Loading

0 comments on commit 0c2298c

Please sign in to comment.