Contract Source Code:
File 1 of 1 : Rebaser
pragma solidity >=0.5.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
contract Ownable {
address public _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () public {
_owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == msg.sender, "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IUniswapV2Pair {
function sync() external;
}
interface IRebaseableERC20 {
function balanceOf(address who) external view returns (uint256);
function rebase(uint256 epoch, uint256 supplyDelta) external returns (uint256);
function totalSupply() external view returns (uint256);
function transferOwnership(address newOwner) external;
}
interface IExchangeRates {
function calculateExchangeRateFor(IERC20 token1, IERC20 token2, address pool, uint256 decimals1, uint256 decimals2, uint256 addedDecimals) external view returns(uint256);
function calculateUsdForToken(address token, address pool, uint256 tokenDecimals, uint256 precision) external view returns(uint256);
function getUsdEtherPrice() external view returns(uint256);
}
contract Rebaser is Ownable {
using SafeMath for uint256;
IUniswapV2Pair public pool = IUniswapV2Pair(0x6c35c40447E8011a63aB05f088fa7cD914d66904); // Address of the IUniswapV2Pair for Weth / Token
IRebaseableERC20 public token = IRebaseableERC20(0xf911a7ec46a2c6fa49193212fe4a2a9B95851c27);
uint256 public tokenDecimals = 9;
IExchangeRates rates = IExchangeRates(0x3eAfb425e22beCFAB10754Ef8BDE68B2AB640384);
uint256 public lastRebase;
uint256 public timeBetweenRebases = 24 hours;
uint256 public lastExchangeRate = 0;
bool public guarded = true;
event RebaseSuccess(uint256 oldPrice, uint256 newPrice, uint256 delta);
event RebaseFail(uint256 oldPrice, uint256 newPrice);
constructor() public {
lastRebase = now;
lastExchangeRate = currentExchangeRate();
}
// Enforces only owner if the guarded
modifier onlyOwnerIfGuarded {
canOperateRebase(msg.sender);
_;
}
// Public function to return if address can operate rebase or not
function canOperateRebase(address _a) public view returns(bool) {
return ((guarded == false) || (_a == _owner));
}
// Size of next rebase
function nextSupplyDelta() public view returns(uint256) {
uint256 currentSupply = token.totalSupply();
if (currentSupply < 100) {
return 0;
}
return currentSupply.div(100);
}
// Public shouldRebase
function shouldRebase(uint256 exchangeRate) public view returns(bool) {
if (exchangeRate < lastExchangeRate) {
return true;
}
return false;
}
// Public exchange rate variable
function currentExchangeRate() public view returns(uint256) {
return rates.calculateUsdForToken({
token: address(token),
pool: address(pool),
tokenDecimals: tokenDecimals,
precision: 4
});
}
// Fully open rebasing. Openned to the public when the owner calls unguard
function rebase() public onlyOwnerIfGuarded {
require(now > lastRebase.add(timeBetweenRebases));
uint256 exchangeRate = currentExchangeRate();
if (shouldRebase(exchangeRate)) {
uint256 supplyDelta = nextSupplyDelta();
token.rebase(0, supplyDelta);
pool.sync();
emit RebaseSuccess(lastExchangeRate, exchangeRate, supplyDelta);
}
else {
emit RebaseFail(lastExchangeRate, exchangeRate);
}
lastRebase = now;
lastExchangeRate = exchangeRate;
}
/*
MANAGEMENT AND TESTING.
*/
// Switches contract from completely owner operated to public operated and gives up management rights.
function unguard() public onlyOwner {
guarded = false;
}
// Only owner operated manual rebasing. This right is given up when unguard() is called
function _rebase() public onlyOwner {
require(guarded == true);
// Get current exchange rate
uint256 exchangeRate = currentExchangeRate();
// Get the proper supply delta
uint256 supplyDelta = nextSupplyDelta();
// Rebase and sync liquidity
token.rebase(0, supplyDelta);
pool.sync();
// Emit success for external services to take action
emit RebaseSuccess(lastExchangeRate, exchangeRate, supplyDelta);
// Sync the state
lastRebase = now;
lastExchangeRate = exchangeRate;
}
// Syncs the exchange rate and rebase to the current transaction state. This right is given up when unguard() is called
function refresh() public onlyOwner {
require(guarded == true);
lastExchangeRate = currentExchangeRate();
lastRebase = now;
}
// Change token to test rebase
function changeToken(address _token) public onlyOwner {
require(guarded == true);
token = IRebaseableERC20(_token);
}
// Change pool to test
function changePool(address _pool) public onlyOwner {
require(guarded == true);
pool = IUniswapV2Pair(_pool);
}
// Modifies the period between rebases
function changePeriod(uint256 _t) public onlyOwner {
require(guarded == true);
timeBetweenRebases = _t;
}
/*
OWNERSHIP
*/
// Transfers the rebase token to a new owner. This right is relinquished by renouncing ownership of the oracle.
function transferTokenOwnership(address newOwner) public onlyOwner {
token.transferOwnership(newOwner);
}
}