Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V4 #2

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open

V4 #2

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
965d14c
vault manager v6 deploys v4 vaults
ewansheldon Jul 23, 2024
ed06e2d
update test with v4 vaults, wip test for vault yield
ewansheldon Jul 23, 2024
dd51886
vault deposits eth to smart vault yield manager when yield deposited
ewansheldon Jul 23, 2024
c24dcfe
test that euro collateral remains the same after swap
ewansheldon Jul 24, 2024
e6ef611
pass euro percentage of yield into yield manager
ewansheldon Jul 24, 2024
13a0777
pseudo code wip of yield
ewansheldon Jul 24, 2024
d917edf
withdraw and collateral calculation wip
ewansheldon Aug 7, 2024
5e0656a
use custom errors in v4 vaults
ewansheldon Aug 14, 2024
1af0353
add function to show underlying collateral values for yield
ewansheldon Aug 14, 2024
7a8d824
deposits yield for both eth + erc20s, of differing decimal accuracies
ewansheldon Aug 15, 2024
1e6ae2d
allows removing of vault data from vault manager, reverts
ewansheldon Aug 16, 2024
8b7becd
protect yield functions for owner only
ewansheldon Aug 19, 2024
bed96f4
add withdraw yield function
ewansheldon Aug 19, 2024
2547466
protect yield functions for owner only
ewansheldon Aug 19, 2024
8ba3f45
refactor yield test
ewansheldon Aug 19, 2024
ed85bbc
remove yield test focus
ewansheldon Aug 19, 2024
2652296
withdraw test
ewansheldon Aug 19, 2024
3e42ce6
withdrawal from EUROs vault
ewansheldon Aug 19, 2024
ca14f5b
underscore private functions for clarity
ewansheldon Aug 19, 2024
123c452
withdrawal from other vaults
ewansheldon Aug 19, 2024
d59e5c3
refactor swapping from euros to eura
ewansheldon Aug 19, 2024
df31d00
rename gamma vaults to hypervisors
ewansheldon Aug 19, 2024
6723325
remove junk abi file
ewansheldon Aug 19, 2024
dc9ef04
test reversions for invalid yield deposit + withdrawal requests
ewansheldon Aug 20, 2024
a379f93
test reversions for invalid yield deposit + withdrawal requests
ewansheldon Aug 20, 2024
ece1801
deposit reverts if vault becomes undercollateralised
ewansheldon Aug 20, 2024
6d56363
withdrawal reverts if collateral value drops below required
ewansheldon Aug 20, 2024
a55cde0
emit deposit + withdraw events
ewansheldon Aug 20, 2024
058c979
remove outdated todo
ewansheldon Aug 20, 2024
a08ff12
require min 10% to euros vault
ewansheldon Aug 20, 2024
ba3e675
skims fee for protocol on yield withdrawal
ewansheldon Aug 21, 2024
82a2c55
protect function which sets fee data
ewansheldon Aug 21, 2024
3c14713
protect function to add hypervisor
ewansheldon Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions contracts/SmartVaultDeployerV4.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;

import "contracts/SmartVaultV4.sol";
import "contracts/PriceCalculator.sol";
import "contracts/interfaces/ISmartVaultDeployer.sol";

contract SmartVaultDeployerV4 is ISmartVaultDeployer {
bytes32 private immutable NATIVE;
address private immutable priceCalculator;

constructor(bytes32 _native, address _clEurUsd) {
NATIVE = _native;
priceCalculator = address(new PriceCalculator(_native, _clEurUsd));
}

function deploy(address _manager, address _owner, address _euros) external returns (address) {
return address(new SmartVaultV4(NATIVE, _manager, _owner, _euros, priceCalculator));
}
}
157 changes: 157 additions & 0 deletions contracts/SmartVaultManagerV6.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;

import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "contracts/interfaces/INFTMetadataGenerator.sol";
import "contracts/interfaces/IEUROs.sol";
import "contracts/interfaces/ISmartVault.sol";
import "contracts/interfaces/ISmartVaultDeployer.sol";
import "contracts/interfaces/ISmartVaultIndex.sol";
import "contracts/interfaces/ISmartVaultManager.sol";
import "contracts/interfaces/ISmartVaultManagerV2.sol";

//
// TODO describe changes
// TODO upgraded zz/zz/zz
//
contract SmartVaultManagerV6 is ISmartVaultManager, ISmartVaultManagerV2, Initializable, ERC721Upgradeable, OwnableUpgradeable {
using SafeERC20 for IERC20;

uint256 public constant HUNDRED_PC = 1e5;

address public protocol;
address public liquidator;
address public euros;
uint256 public collateralRate;
address public tokenManager;
address public smartVaultDeployer;
ISmartVaultIndex private smartVaultIndex;
uint256 private lastToken;
address public nftMetadataGenerator;
uint256 public mintFeeRate;
uint256 public burnFeeRate;
uint256 public swapFeeRate;
address public weth;
address public swapRouter;
address public swapRouter2;
uint16 public userVaultLimit;
address public yieldManager;

event VaultDeployed(address indexed vaultAddress, address indexed owner, address vaultType, uint256 tokenId);
event VaultLiquidated(address indexed vaultAddress);
event VaultTransferred(uint256 indexed tokenId, address from, address to);

struct SmartVaultData {
uint256 tokenId; uint256 collateralRate; uint256 mintFeeRate;
uint256 burnFeeRate; ISmartVault.Status status;
}

function initialize() initializer public {}

modifier onlyLiquidator {
require(msg.sender == liquidator, "err-invalid-liquidator");
_;
}

function vaultIDs(address _holder) public view returns (uint256[] memory) {
return smartVaultIndex.getTokenIds(_holder);
}

function vaultData(uint256 _tokenID) external view returns (SmartVaultData memory) {
return SmartVaultData({
tokenId: _tokenID,
collateralRate: collateralRate,
mintFeeRate: mintFeeRate,
burnFeeRate: burnFeeRate,
status: ISmartVault(smartVaultIndex.getVaultAddress(_tokenID)).status()
});
}

function mint() external returns (address vault, uint256 tokenId) {
tokenId = lastToken + 1;
_safeMint(msg.sender, tokenId);
lastToken = tokenId;
vault = ISmartVaultDeployer(smartVaultDeployer).deploy(address(this), msg.sender, euros);
smartVaultIndex.addVaultAddress(tokenId, payable(vault));
IEUROs(euros).grantRole(IEUROs(euros).MINTER_ROLE(), vault);
IEUROs(euros).grantRole(IEUROs(euros).BURNER_ROLE(), vault);
emit VaultDeployed(vault, msg.sender, euros, tokenId);
}

function liquidateVault(uint256 _tokenId) external onlyLiquidator {
ISmartVault vault = ISmartVault(smartVaultIndex.getVaultAddress(_tokenId));
try vault.undercollateralised() returns (bool _undercollateralised) {
require(_undercollateralised, "vault-not-undercollateralised");
vault.liquidate();
IEUROs(euros).revokeRole(IEUROs(euros).MINTER_ROLE(), address(vault));
IEUROs(euros).revokeRole(IEUROs(euros).BURNER_ROLE(), address(vault));
emit VaultLiquidated(address(vault));
} catch {
revert("other-liquidation-error");
}
}

function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
ISmartVault.Status memory vaultStatus = ISmartVault(smartVaultIndex.getVaultAddress(_tokenId)).status();
return INFTMetadataGenerator(nftMetadataGenerator).generateNFTMetadata(_tokenId, vaultStatus);
}

function totalSupply() external view returns (uint256) {
return lastToken;
}

function setMintFeeRate(uint256 _rate) external onlyOwner {
mintFeeRate = _rate;
}

function setBurnFeeRate(uint256 _rate) external onlyOwner {
burnFeeRate = _rate;
}

function setSwapFeeRate(uint256 _rate) external onlyOwner {
swapFeeRate = _rate;
}

function setWethAddress(address _weth) external onlyOwner() {
weth = _weth;
}

function setSwapRouter2(address _swapRouter) external onlyOwner() {
swapRouter2 = _swapRouter;
}

function setNFTMetadataGenerator(address _nftMetadataGenerator) external onlyOwner() {
nftMetadataGenerator = _nftMetadataGenerator;
}

function setSmartVaultDeployer(address _smartVaultDeployer) external onlyOwner() {
smartVaultDeployer = _smartVaultDeployer;
}

function setProtocolAddress(address _protocol) external onlyOwner() {
protocol = _protocol;
}

function setLiquidatorAddress(address _liquidator) external onlyOwner() {
liquidator = _liquidator;
}

function setUserVaultLimit(uint16 _userVaultLimit) external onlyOwner() {
userVaultLimit = _userVaultLimit;
}

function setYieldManager(address _yieldManager) external onlyOwner() {
yieldManager = _yieldManager;
}

// TODO test transfer
function _afterTokenTransfer(address _from, address _to, uint256 _tokenId, uint256) internal override {
require(vaultIDs(_to).length < userVaultLimit, "err-vault-limit");
smartVaultIndex.transferTokenId(_from, _to, _tokenId);
if (address(_from) != address(0)) ISmartVault(smartVaultIndex.getVaultAddress(_tokenId)).setOwner(_to);
emit VaultTransferred(_tokenId, _from, _to);
}
}
Loading