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

DD-1448 Yearn deploy real [WIP] #44

Open
wants to merge 10 commits into
base: test-staking
Choose a base branch
from
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ types/*
# Environment
.env


# coverage/profiler report
coverage
coverage.json

#VSCode project
.vscode

# MacOS junk
.DS_Store
10 changes: 7 additions & 3 deletions contracts/test/CErc20Stub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ contract CErc20Stub is Base, ICErc20, ERC20, ERC20Detailed {

uint256 public constant EXP_SCALE = 1e18; //Exponential scale (see Compound Exponential)
uint256 public constant INTEREST_RATE = 10 * EXP_SCALE / 100; // Annual interest 10%
uint256 public constant INITIAL_RATE = 200000000000000000000000000; // Same as real cDAI
uint256 public constant INITIAL_RATE_BASE = 20000000; // Same as real cTokens, will be multiblied by 1e<DECIMALS>
uint256 public constant ANNUAL_SECONDS = 365*24*60*60+(24*60*60/4); // Seconds in a year + 1/4 day to compensate leap years
uint256 private constant NO_ERROR = 0;

FreeERC20 underlying;
uint256 initialRate;
uint256 created;

function initialize(address _underlying) public initializer {
Base.initialize();
ERC20Detailed.initialize("Compound Dai", "cDAI", 8);
string memory name = string(abi.encodePacked("Compound ", ERC20Detailed(_underlying).symbol()));
string memory symbol = string(abi.encodePacked("c", ERC20Detailed(_underlying).symbol()));
initialRate = INITIAL_RATE_BASE * (10 ** uint256(ERC20Detailed(_underlying).decimals()));
ERC20Detailed.initialize(name, symbol, 8);
underlying = FreeERC20(_underlying);
created = now;
}
Expand Down Expand Up @@ -77,6 +81,6 @@ contract CErc20Stub is Base, ICErc20, ERC20, ERC20Detailed {

function _exchangeRate() internal view returns (uint256) {
uint256 sec = now.sub(created);
return INITIAL_RATE.add(INITIAL_RATE.mul(INTEREST_RATE).mul(sec).div(ANNUAL_SECONDS).div(EXP_SCALE));
return initialRate.add(initialRate.mul(INTEREST_RATE).mul(sec).div(ANNUAL_SECONDS).div(EXP_SCALE));
}
}
67 changes: 67 additions & 0 deletions contracts/test/yearn/AaveStub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
pragma solidity ^0.5.0;

import "../../common/Base.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol";

import "./Interfaces.sol";

contract ATokenStub is Base, ERC20, ERC20Detailed, AToken {
using SafeERC20 for IERC20;

IERC20 public underlying;

function initialize(address _underlying) public initializer {
Base.initialize();
underlying = IERC20(_underlying);
string memory name = string(abi.encodePacked("Aave Interest bearing ", ERC20Detailed(_underlying).symbol()));
string memory symbol = string(abi.encodePacked("a", ERC20Detailed(_underlying).symbol()));
uint8 decimals = ERC20Detailed(_underlying).decimals();
ERC20Detailed.initialize(name, symbol, decimals);
}

function ownerMint(address receiver, uint256 amount) external onlyOwner {
_mint(receiver, amount);
}

function redeem(uint256 amount) external {
_burnFrom(_msgSender(), amount);
underlying.safeTransfer(_msgSender(), amount);
}

}

contract AaveStub is Base, LendingPoolAddressesProvider, Aave {
using SafeERC20 for IERC20;

mapping(address=>address) public tokens;

function initialize() public initializer {
Base.initialize();
}

function createAToken(address _underlying) external onlyOwner {
ATokenStub aToken = new ATokenStub();
aToken.initialize(_underlying);
tokens[_underlying] = address(aToken);
}


function deposit(address _reserve, uint256 _amount, uint16 /*_referralCode*/) external {
address aToken = tokens[_reserve];
require(aToken != address(0), "Reserve token not supported");
IERC20(_reserve).safeTransferFrom(_msgSender(), aToken, _amount);
ATokenStub(aToken).ownerMint(_msgSender(), _amount);
}

function getLendingPool() external view returns (address) {
return address(this);
}

function getLendingPoolCore() external view returns (address) {
return address(this);
}

}
75 changes: 75 additions & 0 deletions contracts/test/yearn/DyDxStub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

import "../../common/Base.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";


import "./Interfaces.sol";
import "./DyDxStructs.sol";

contract DyDxStub is Base, DyDx {
using SafeMath for uint256;
using SafeERC20 for IERC20;

event MarketAdded(address token, uint256 market);

struct AccountBalances {
mapping(address=>uint256) tokens;
}

uint256 numMarkets;
mapping(uint256 => address) public markets;
mapping(address=>AccountBalances) balances;

function addMarket(address token) external onlyOwner {
numMarkets += 1;
markets[numMarkets] = token;
emit MarketAdded(token, numMarkets);
}

function getAccountWei(Info memory account, uint256 marketId) public view returns (Wei memory) {
address beneficiary = account.owner;
address token = markets[marketId];
require(token != address(0), "Market not found");
return Wei({
sign: true,
value: balances[beneficiary].tokens[token]
});
}

function operate(Info[] memory accounts, ActionArgs[] memory args) public {
require(accounts.length == args.length, "Array size mismatch");
for(uint256 i=0; i< accounts.length; i++) {
_operate(accounts[i], args[i]);
}
}

function _operate(Info memory account, ActionArgs memory arg) internal {
address beneficiary = account.owner;
address token = markets[arg.primaryMarketId];
require(token != address(0), "Market not found");
uint256 amount = arg.amount.value;
if(arg.actionType == ActionType.Deposit) {
_deposit(token, beneficiary, amount);
} else if(arg.actionType == ActionType.Deposit) {
_withdraw(token, beneficiary, amount);
} else {
revert("Unsupported action");
}
}

function _deposit(address token, address beneficiary, uint256 amount) internal {
IERC20(token).safeTransferFrom(beneficiary, address(this), amount);
balances[beneficiary].tokens[token] = balances[beneficiary].tokens[token].add(amount);
}

function _withdraw(address token, address beneficiary, uint256 amount) internal {
balances[beneficiary].tokens[token] = balances[beneficiary].tokens[token].sub(amount);
IERC20(token).safeTransfer(beneficiary, amount);
}
}
54 changes: 54 additions & 0 deletions contracts/test/yearn/DydxStructs.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

contract Structs {
struct Val {
uint256 value;
}

enum ActionType {
Deposit, // supply tokens
Withdraw // borrow tokens
}

enum AssetDenomination {
Wei // the amount is denominated in wei
}

enum AssetReference {
Delta // the amount is given as a delta from the current value
}

struct AssetAmount {
bool sign; // true if positive
AssetDenomination denomination;
AssetReference ref;
uint256 value;
}

struct ActionArgs {
ActionType actionType;
uint256 accountId;
AssetAmount amount;
uint256 primaryMarketId;
uint256 secondaryMarketId;
address otherAddress;
uint256 otherAccountId;
bytes data;
}

struct Info {
address owner; // The address that owns the account
uint256 number; // A nonce that allows a single address to control many accounts
}

struct Wei {
bool sign; // true if positive
uint256 value;
}
}

contract DyDx is Structs {
function getAccountWei(Info memory account, uint256 marketId) public view returns (Wei memory);
function operate(Info[] memory, ActionArgs[] memory) public;
}
79 changes: 79 additions & 0 deletions contracts/test/yearn/ERC20mod.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
pragma solidity ^0.5.0;

import "@openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";


contract ERC20 is Context, IERC20 {
using SafeMath for uint256;

mapping (address => uint256) _balances;

mapping (address => mapping (address => uint256)) private _allowances;

uint256 _totalSupply;
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");

_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");

_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");

_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal {
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);
}
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
}
}
41 changes: 41 additions & 0 deletions contracts/test/yearn/FulcrumStub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pragma solidity ^0.5.0;

import "../../common/Base.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol";

import "./Interfaces.sol";

contract FulcrumStub is Base, ERC20, ERC20Detailed, Fulcrum {
using SafeERC20 for IERC20;

IERC20 public underlying;

function initialize(address _underlying) public initializer {
Base.initialize();
underlying = IERC20(_underlying);
string memory name = string(abi.encodePacked("Fulcrum ", ERC20Detailed(_underlying).symbol(), "iToken"));
string memory symbol = string(abi.encodePacked("i", ERC20Detailed(_underlying).symbol()));
uint8 decimals = ERC20Detailed(_underlying).decimals();
ERC20Detailed.initialize(name, symbol, decimals);
}


function mint(address receiver, uint256 amount) external payable returns (uint256 mintAmount) {
underlying.safeTransferFrom(_msgSender(), address(this), amount);
_mint(receiver, amount);
return mintAmount;
}

function burn(address receiver, uint256 burnAmount) external returns (uint256 loanAmountPaid) {
_burnFrom(_msgSender(), burnAmount);
underlying.safeTransfer(receiver, burnAmount);
return burnAmount;
}

function assetBalanceOf(address _owner) external view returns (uint256 balance) {
return balanceOf(_owner);
}
}
Loading