Skip to content

Commit

Permalink
Merge d2812d8 into 5cad7f9
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerry Smith committed Jan 9, 2021
2 parents 5cad7f9 + d2812d8 commit b233135
Show file tree
Hide file tree
Showing 9 changed files with 461 additions and 56 deletions.
56 changes: 29 additions & 27 deletions contracts/Treasury.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';

import './interfaces/IOracle.sol';
import './interfaces/IBoardroom.sol';
import './interfaces/IBasisAsset.sol';
import './interfaces/ISimpleERCFund.sol';
import './lib/Babylonian.sol';
import './lib/FixedPoint.sol';
import './lib/Safe112.sol';
import './owner/Operator.sol';
import './utils/Epoch.sol';
import './utils/ContractGuard.sol';
import {ICurve} from './curve/Curve.sol';
import {IOracle} from './interfaces/IOracle.sol';
import {IBoardroom} from './interfaces/IBoardroom.sol';
import {IBasisAsset} from './interfaces/IBasisAsset.sol';
import {ISimpleERCFund} from './interfaces/ISimpleERCFund.sol';
import {Babylonian} from './lib/Babylonian.sol';
import {FixedPoint} from './lib/FixedPoint.sol';
import {Safe112} from './lib/Safe112.sol';
import {Operator} from './owner/Operator.sol';
import {Epoch} from './utils/Epoch.sol';
import {ContractGuard} from './utils/ContractGuard.sol';

/**
* @title Basis Cash Treasury contract
Expand All @@ -39,14 +40,14 @@ contract Treasury is ContractGuard, Epoch {
address public cash;
address public bond;
address public share;
address public curve;
address public boardroom;

address public bondOracle;
address public seigniorageOracle;

// ========== PARAMS
uint256 public cashPriceOne;
uint256 public cashPriceCeiling;

uint256 private accumulatedSeigniorage = 0;
uint256 private lastBondOracleEpoch = 0;
Expand All @@ -64,19 +65,20 @@ contract Treasury is ContractGuard, Epoch {
address _seigniorageOracle,
address _boardroom,
address _fund,
address _curve,
uint256 _startTime
) public Epoch(1 days, _startTime, 0) {
cash = _cash;
bond = _bond;
share = _share;
curve = _curve;
bondOracle = _bondOracle;
seigniorageOracle = _seigniorageOracle;

boardroom = _boardroom;
fund = _fund;

cashPriceOne = 10**18;
cashPriceCeiling = uint256(105).mul(cashPriceOne).div(10**2);
}

/* =================== Modifier =================== */
Expand Down Expand Up @@ -116,6 +118,10 @@ contract Treasury is ContractGuard, Epoch {
return IERC20(cash).totalSupply().sub(accumulatedSeigniorage);
}

function getCeilingPrice() public view returns (uint256) {
return ICurve(curve).calcCeiling(circulatingSupply());
}

// oracle
function getBondOraclePrice() public view returns (uint256) {
return _getCashPrice(bondOracle);
Expand All @@ -139,9 +145,6 @@ contract Treasury is ContractGuard, Epoch {
function initialize() public checkOperator {
require(!initialized, 'Treasury: initialized');

// burn all of it's balance
IBasisAsset(cash).burn(IERC20(cash).balanceOf(address(this)));

// set accumulatedSeigniorage to it's balance
accumulatedSeigniorage = IERC20(cash).balanceOf(address(this));

Expand Down Expand Up @@ -198,10 +201,10 @@ contract Treasury is ContractGuard, Epoch {
}

// TWEAK
function setCashPriceCeiling(uint256 newCeiling) public onlyOperator {
uint256 oldCeiling = cashPriceCeiling;
cashPriceCeiling = newCeiling;
emit CashPriceCeilingChanged(msg.sender, oldCeiling, newCeiling);
function setCeilingCurve(address newCurve) public onlyOperator {
address oldCurve = newCurve;
curve = newCurve;
emit CeilingCurveChanged(msg.sender, oldCurve, newCurve);
}

/* ========== MUTABLE FUNCTIONS ========== */
Expand Down Expand Up @@ -237,7 +240,7 @@ contract Treasury is ContractGuard, Epoch {
require(amount > 0, 'Treasury: cannot purchase bonds with zero amount');

uint256 cashPrice = _getCashPrice(bondOracle);
require(cashPrice == targetPrice, 'Treasury: cash price moved');
require(cashPrice <= targetPrice, 'Treasury: cash price moved');
require(
cashPrice < cashPriceOne, // price < $1
'Treasury: cashPrice not eligible for bond purchase'
Expand All @@ -263,7 +266,7 @@ contract Treasury is ContractGuard, Epoch {
emit BoughtBonds(msg.sender, amount);
}

function redeemBonds(uint256 amount, uint256 targetPrice)
function redeemBonds(uint256 amount)
external
onlyOneBlock
checkMigration
Expand All @@ -274,9 +277,8 @@ contract Treasury is ContractGuard, Epoch {
require(amount > 0, 'Treasury: cannot redeem bonds with zero amount');

uint256 cashPrice = _getCashPrice(bondOracle);
require(cashPrice == targetPrice, 'Treasury: cash price moved');
require(
cashPrice > cashPriceCeiling, // price > $1.05
cashPrice > getCeilingPrice(), // price > $1.05
'Treasury: cashPrice not eligible for bond purchase'
);
require(
Expand Down Expand Up @@ -304,7 +306,7 @@ contract Treasury is ContractGuard, Epoch {
{
_updateCashPrice();
uint256 cashPrice = _getCashPrice(seigniorageOracle);
if (cashPrice <= cashPriceCeiling) {
if (cashPrice <= getCeilingPrice()) {
return; // just advance epoch instead revert
}

Expand Down Expand Up @@ -374,10 +376,10 @@ contract Treasury is ContractGuard, Epoch {
address oldOracle,
address newOracle
);
event CashPriceCeilingChanged(
event CeilingCurveChanged(
address indexed operator,
uint256 oldCeiling,
uint256 newCeiling
address oldCurve,
address newCurve
);

// CORE
Expand Down
82 changes: 82 additions & 0 deletions contracts/curve/Curve.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
pragma solidity ^0.6.0;

interface ICurve {
function minSupply() external view returns (uint256);

function maxSupply() external view returns (uint256);

function minCeiling() external view returns (uint256);

function maxCeiling() external view returns (uint256);

function calcCeiling(uint256 _supply) external view returns (uint256);
}

abstract contract Curve is ICurve {
/* ========== EVENTS ========== */

event MinSupplyChanged(
address indexed operator,
uint256 _old,
uint256 _new
);

event MaxSupplyChanged(
address indexed operator,
uint256 _old,
uint256 _new
);

event MinCeilingChanged(
address indexed operator,
uint256 _old,
uint256 _new
);

event MaxCeilingChanged(
address indexed operator,
uint256 _old,
uint256 _new
);

/* ========== STATE VARIABLES ========== */

uint256 public override minSupply;
uint256 public override maxSupply;

uint256 public override minCeiling;
uint256 public override maxCeiling;

/* ========== GOVERNANCE ========== */

function setMinSupply(uint256 _newMinSupply) public virtual {
uint256 oldMinSupply = minSupply;
minSupply = _newMinSupply;
emit MinSupplyChanged(msg.sender, oldMinSupply, _newMinSupply);
}

function setMaxSupply(uint256 _newMaxSupply) public virtual {
uint256 oldMaxSupply = maxSupply;
maxSupply = _newMaxSupply;
emit MaxSupplyChanged(msg.sender, oldMaxSupply, _newMaxSupply);
}

function setMinCeiling(uint256 _newMinCeiling) public virtual {
uint256 oldMinCeiling = _newMinCeiling;
minCeiling = _newMinCeiling;
emit MinCeilingChanged(msg.sender, oldMinCeiling, _newMinCeiling);
}

function setMaxCeiling(uint256 _newMaxCeiling) public virtual {
uint256 oldMaxCeiling = _newMaxCeiling;
maxCeiling = _newMaxCeiling;
emit MaxCeilingChanged(msg.sender, oldMaxCeiling, _newMaxCeiling);
}

function calcCeiling(uint256 _supply)
external
view
virtual
override
returns (uint256);
}
73 changes: 73 additions & 0 deletions contracts/curve/Linear.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
pragma solidity ^0.6.0;

import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';

import {Operator} from '../owner/Operator.sol';
import {Curve} from './Curve.sol';

contract LinearThreshold is Operator, Curve {
using SafeMath for uint256;

/* ========== CONSTRUCTOR ========== */

constructor(
uint256 _minSupply,
uint256 _maxSupply,
uint256 _minCeiling,
uint256 _maxCeiling
) public {
minSupply = _minSupply;
maxSupply = _maxSupply;
minCeiling = _minCeiling;
maxCeiling = _maxCeiling;
}

/* ========== GOVERNANCE ========== */

function setMinSupply(uint256 _newMinSupply) public override onlyOperator {
super.setMinSupply(_newMinSupply);
}

function setMaxSupply(uint256 _newMaxSupply) public override onlyOperator {
super.setMaxSupply(_newMaxSupply);
}

function setMinCeiling(uint256 _newMinCeiling)
public
override
onlyOperator
{
super.setMinCeiling(_newMinCeiling);
}

function setMaxCeiling(uint256 _newMaxCeiling)
public
override
onlyOperator
{
super.setMaxCeiling(_newMaxCeiling);
}

/* ========== VIEW FUNCTIONS ========== */

function calcCeiling(uint256 _supply)
public
view
override
returns (uint256)
{
if (_supply <= minSupply) {
return maxCeiling;
}
if (_supply >= maxSupply) {
return minCeiling;
}

uint256 slope =
maxCeiling.sub(minCeiling).mul(1e18).div(maxSupply.sub(minSupply));
uint256 ceiling =
maxCeiling.sub(slope.mul(_supply.sub(minSupply)).div(1e18));

return ceiling;
}
}

0 comments on commit b233135

Please sign in to comment.