Skip to content

Commit

Permalink
Add base currency
Browse files Browse the repository at this point in the history
  • Loading branch information
Maroutis committed Jun 9, 2023
1 parent 79de9e2 commit 76e7104
Show file tree
Hide file tree
Showing 36 changed files with 7,887 additions and 570 deletions.
2 changes: 1 addition & 1 deletion PortfolioOptimizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ async function calculatePortfolio() {
let maxSrReturns = retArr[maxSharpeIdx];
let maxSrVolatility = volArr[maxSharpeIdx];

return allWeights[maxSharpeIdx][0] * 100;
return parseInt(allWeights[maxSharpeIdx][0] * 100);
}

async function main() {
Expand Down
164 changes: 164 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686322567.json

Large diffs are not rendered by default.

331 changes: 331 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686322575.json

Large diffs are not rendered by default.

331 changes: 331 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686322603.json

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686323541.json

Large diffs are not rendered by default.

331 changes: 331 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686323548.json

Large diffs are not rendered by default.

331 changes: 331 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686323630.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686326497.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686326511.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686326588.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686327302.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686327340.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686327418.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686327745.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686327759.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686327841.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686328057.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686328071.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686328174.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686329641.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686329655.json

Large diffs are not rendered by default.

387 changes: 387 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686329738.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686333107.json

Large diffs are not rendered by default.

326 changes: 326 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686333139.json

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686333197.json

Large diffs are not rendered by default.

326 changes: 326 additions & 0 deletions broadcast/DeployProtocol.s.sol/11155111/run-1686333210.json

Large diffs are not rendered by default.

293 changes: 172 additions & 121 deletions broadcast/DeployProtocol.s.sol/11155111/run-latest.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions script/DeployProtocol.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ contract DeployProtocol is Script {
address uniswapV2Router = 0xC532a74256D3Db42D0Bf7a0400fEFDbad7694008;
address priceFeedBenchmark = 0x694AA1769357215DE4FAC081bf1f309aDC325306;
uint256 minRatio = 100;
address WETH = 0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9;
IERC20 weth = IERC20(WETH);
uint256 amountToMint1 = 10 ** 18;

vm.startBroadcast(deployerPrivateKey);

Expand All @@ -25,6 +28,9 @@ contract DeployProtocol is Script {
notary.activate(address(coin), address(portfolio));
Vault vault = Vault(notary.openVault(priceFeedBenchmark));

weth.approve(address(vault), amountToMint1);
coin.approve(address(vault), amountToMint1 * 10);

vm.stopBroadcast();
}
}
70 changes: 30 additions & 40 deletions src/BasketHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct Basket {
mapping(IERC20 => uint8) decimals;
mapping(IERC20 => uint256) weightsInPercent; // {ref/BU}
mapping(IERC20 => AggregatorV3Interface) priceFeedBasket;
mapping(IERC20 => string) baseCurrency;
bool empty; // The struct is not imported if the bool is not added (solidity bug ?)
}

Expand All @@ -22,6 +23,7 @@ struct Basket {
*/
library BasketLib {
uint256 constant FIX_ZERO = 0;

using PriceConverter for uint256;

function empty(Basket storage self, IERC20 token) internal {
Expand All @@ -30,7 +32,7 @@ library BasketLib {
delete self.priceFeedBasket[token];

uint256 length = self.erc20s.length;
for (uint i = 0; i < length; i++) {
for (uint256 i = 0; i < length; i++) {
if (self.erc20s[i] == token) {
self.erc20s[i] = self.erc20s[length - 1];
self.erc20s.pop();
Expand All @@ -48,6 +50,7 @@ library BasketLib {
delete self.tokenAmts[self.erc20s[i]];
delete self.weightsInPercent[self.erc20s[i]];
delete self.priceFeedBasket[self.erc20s[i]];
delete self.baseCurrency[self.erc20s[i]];
}
delete self.erc20s;
}
Expand All @@ -58,7 +61,8 @@ library BasketLib {
uint256[] memory tokenAmts,
uint8[] memory decimals,
uint256[] memory weightsInPercent,
AggregatorV3Interface[] memory priceFeedBasket
AggregatorV3Interface[] memory priceFeedBasket,
string[] memory baseCurrency
) internal {
empty(self);
uint256 length = erc20s.length;
Expand All @@ -68,6 +72,7 @@ library BasketLib {
self.decimals[IERC20(erc20s[i])] = decimals[i];
self.weightsInPercent[IERC20(erc20s[i])] = weightsInPercent[i];
self.priceFeedBasket[IERC20(erc20s[i])] = priceFeedBasket[i];
self.baseCurrency[IERC20(erc20s[i])] = baseCurrency[i];
}
}

Expand All @@ -78,27 +83,18 @@ library BasketLib {
for (uint256 i = 0; i < length; ++i) {
self.erc20s.push(other.erc20s[i]);
self.tokenAmts[other.erc20s[i]] = other.tokenAmts[other.erc20s[i]];
self.weightsInPercent[other.erc20s[i]] = other.weightsInPercent[
other.erc20s[i]
];
self.priceFeedBasket[other.erc20s[i]] = other.priceFeedBasket[
other.erc20s[i]
];
self.weightsInPercent[other.erc20s[i]] = other.weightsInPercent[other.erc20s[i]];
self.priceFeedBasket[other.erc20s[i]] = other.priceFeedBasket[other.erc20s[i]];
}
}

function updateWeights(
Basket storage self,
AggregatorV3Interface _priceFeedBenchmark
) internal {
function updateWeights(Basket storage self, AggregatorV3Interface _priceFeedBenchmark) internal {
uint256 length = self.erc20s.length;
for (uint256 i = 0; i < length; ++i) {
IERC20 _tok = self.erc20s[i];
self.weightsInPercent[_tok] = ((getSingleBalance(
self,
_tok,
_priceFeedBenchmark
) * 100) / getBasketBalance(self, _priceFeedBenchmark));
self.weightsInPercent[_tok] = (
(getSingleBalance(self, _tok, _priceFeedBenchmark) * 100) / getBasketBalance(self, _priceFeedBenchmark)
);
}
}

Expand All @@ -111,6 +107,7 @@ library BasketLib {
uint256 _amount,
uint8 _decimal,
AggregatorV3Interface _priceFeed,
string memory _baseCurrency,
AggregatorV3Interface _priceFeedBenchmark
) internal {
if (_amount == FIX_ZERO) return;
Expand All @@ -119,18 +116,16 @@ library BasketLib {
self.tokenAmts[_tok] = _amount;
self.decimals[_tok] = _decimal;
self.priceFeedBasket[_tok] = _priceFeed;
self.baseCurrency[_tok] = _baseCurrency;
} else {
self.tokenAmts[_tok] += _amount;
}
updateWeights(self, _priceFeedBenchmark);
}

function reduce(
Basket storage self,
IERC20 _tok,
uint256 _amount,
AggregatorV3Interface _priceFeedBenchmark
) internal {
function reduce(Basket storage self, IERC20 _tok, uint256 _amount, AggregatorV3Interface _priceFeedBenchmark)
internal
{
if (_amount == FIX_ZERO) return;
if (self.tokenAmts[_tok] == _amount) {
empty(self, _tok);
Expand All @@ -149,29 +144,24 @@ library BasketLib {
empty(self);
}

function getSingleBalance(
Basket storage self,
IERC20 token,
AggregatorV3Interface _priceFeedBenchmark
) internal view returns (uint256 balance) {
function getSingleBalance(Basket storage self, IERC20 token, AggregatorV3Interface _priceFeedBenchmark)
internal
view
returns (uint256 balance)
{
balance = self.tokenAmts[token].getConversionRate(
self.priceFeedBasket[token],
self.decimals[token],
_priceFeedBenchmark
self.priceFeedBasket[token], self.decimals[token], _priceFeedBenchmark, self.baseCurrency[token]
);
}

function getBasketBalance(
Basket storage self,
AggregatorV3Interface _priceFeedBenchmark
) internal view returns (uint256 balance) {
function getBasketBalance(Basket storage self, AggregatorV3Interface _priceFeedBenchmark)
internal
view
returns (uint256 balance)
{
uint256 length = self.erc20s.length;
for (uint256 i = 0; i < length; ++i) {
balance += getSingleBalance(
self,
self.erc20s[i],
_priceFeedBenchmark
);
balance += getSingleBalance(self, self.erc20s[i], _priceFeedBenchmark);
}
}
}
2 changes: 0 additions & 2 deletions src/Coin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
pragma solidity ^0.8.0;

import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "lib/openzeppelin-contracts/contracts/access/Ownable.sol";
import "lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol";
import "lib/chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "./BasketHandler.sol";
import "./PriceConverter.sol";
Expand Down
51 changes: 12 additions & 39 deletions src/Notary.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ pragma solidity ^0.8.0;

import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "lib/openzeppelin-contracts/contracts/access/Ownable.sol";
import "lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol";
import "lib/chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "lib/chainlink/contracts/src/v0.8/interfaces/automation/KeeperCompatibleInterface.sol";
import "./BasketHandler.sol";
import "./PriceConverter.sol";
import "./Vault.sol";

/**
Expand Down Expand Up @@ -47,10 +43,7 @@ contract Notary is Ownable, KeeperCompatibleInterface {
* @dev Activates the notary by providing the address of a token contract
* that has been configured to reference this address.
*/
function activate(
address _coinAddress,
address _portfolio
) public onlyOwner {
function activate(address _coinAddress, address _portfolio) public onlyOwner {
// @Todo check for notary address, investigate recursive implications.
coinAddress = _coinAddress;
portfolioAddress = _portfolio;
Expand All @@ -60,9 +53,7 @@ contract Notary is Ownable, KeeperCompatibleInterface {
/**
* @dev Opens a position for a specified vault owner address.
*/
function openVault(
address s_priceFeedBenchmark
) public isActivated returns (address) {
function openVault(address s_priceFeedBenchmark) public isActivated returns (address) {
Vault vault = new Vault(
coinAddress,
address(this),
Expand All @@ -79,12 +70,10 @@ contract Notary is Ownable, KeeperCompatibleInterface {
return vaultAddress;
}

function checkUpkeep(
bytes memory /*checkData*/
)
function checkUpkeep(bytes memory /*checkData*/ )
public
override
returns (bool upkeepNeeded, bytes memory /*performData*/)
returns (bool upkeepNeeded, bytes memory /*performData*/ )
{
bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
bool hasUsers = (Vault(vaultAddress).getUsers().length > 0);
Expand All @@ -93,11 +82,11 @@ contract Notary is Ownable, KeeperCompatibleInterface {
// * performUpkeep or not.
}

function performUpkeep(bytes calldata /*performData*/) external override {
function performUpkeep(bytes calldata /*performData*/ ) external override {
// Request the random number
// Once we get it, do something with it
// 2 transaction process
(bool upkeepNeeded, ) = checkUpkeep("");
(bool upkeepNeeded,) = checkUpkeep("");
if (!upkeepNeeded) {}

liquidateVaults();
Expand Down Expand Up @@ -134,15 +123,8 @@ contract Notary is Ownable, KeeperCompatibleInterface {
Vault vault = Vault(vaultAddress);
uint256 numUsers = vault.getUsers().length;
for (uint256 j = 0; j < numUsers; j++) {
if (
vault.getStrategy(vault.getUsers()[j]) ==
Portfolio.STRATEGY.DYNAMIC_MODEL
) {
vault.updateCollateralPortfolio(
weth,
_poolFee,
vault.getUsers()[j]
);
if (vault.getStrategy(vault.getUsers()[j]) == Portfolio.STRATEGY.DYNAMIC_MODEL) {
vault.updateCollateralPortfolio(weth, _poolFee, vault.getUsers()[j]);
}
}
}
Expand All @@ -152,27 +134,18 @@ contract Notary is Ownable, KeeperCompatibleInterface {
uint256[] memory _targetWeights,
uint8[] memory _decimals,
AggregatorV3Interface[] memory _priceFeeds,
string[] memory _baseCurrencies,
address weth,
uint24 _poolFee
) public onlyOwner {
Portfolio(portfolioAddress).updateAssets(
_assetsAddress,
_targetWeights,
_decimals,
_priceFeeds
_assetsAddress, _targetWeights, _decimals, _priceFeeds, _baseCurrencies
);
Vault vault = Vault(vaultAddress);
uint256 numUsers = vault.getUsers().length;
for (uint256 j = 0; j < numUsers; j++) {
if (
vault.getStrategy(vault.getUsers()[j]) ==
Portfolio.STRATEGY.DYNAMIC_MODEL
) {
vault.updateCollateralPortfolio(
weth,
_poolFee,
vault.getUsers()[j]
);
if (vault.getStrategy(vault.getUsers()[j]) == Portfolio.STRATEGY.DYNAMIC_MODEL) {
vault.updateCollateralPortfolio(weth, _poolFee, vault.getUsers()[j]);
}
}
}
Expand Down
Loading

0 comments on commit 76e7104

Please sign in to comment.