// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IFloor {
function refund(address receiver, uint256 burnAmount) external returns (uint256);
function capital() external view returns (uint256);
function getMaxMintAmount(uint256 ethAmount) external view returns (uint256);
function getRefundAmount(uint256 _tokenAmount) external view returns (uint256);
}
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IXVIX {
function maxSupply() external view returns (uint256);
function mint(address account, uint256 amount) external returns (bool);
function burn(address account, uint256 amount) external returns (bool);
function toast(uint256 amount) external returns (bool);
function rebase() external returns (bool);
}
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
//SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./libraries/math/SafeMath.sol";
import "./libraries/token/IERC20.sol";
import "./interfaces/IXVIX.sol";
import "./interfaces/IFloor.sol";
contract XVIX is IERC20, IXVIX {
using SafeMath for uint256;
struct TransferConfig {
bool active;
uint256 senderBurnBasisPoints;
uint256 senderFundBasisPoints;
uint256 receiverBurnBasisPoints;
uint256 receiverFundBasisPoints;
}
uint256 public constant BASIS_POINTS_DIVISOR = 10000;
uint256 public constant MAX_FUND_BASIS_POINTS = 20; // 0.2%
uint256 public constant MAX_BURN_BASIS_POINTS = 500; // 5%
uint256 public constant MIN_REBASE_INTERVAL = 30 minutes;
uint256 public constant MAX_REBASE_INTERVAL = 1 weeks;
// cap the max intervals per rebase to avoid uint overflow errors
uint256 public constant MAX_INTERVALS_PER_REBASE = 10;
uint256 public constant MAX_REBASE_BASIS_POINTS = 500; // 5%
// cap the normalDivisor to avoid uint overflow errors
// the normalDivisor will be reached about 20 years after the first rebase
uint256 public constant MAX_NORMAL_DIVISOR = 10**23;
uint256 public constant SAFE_DIVISOR = 10**8;
string public constant name = "XVIX";
string public constant symbol = "XVIX";
uint8 public constant decimals = 18;
string public website = "https://xvix.finance/";
address public gov;
address public minter;
address public floor;
address public distributor;
address public fund;
uint256 public _normalSupply;
uint256 public _safeSupply;
uint256 public override maxSupply;
uint256 public normalDivisor = 10**8;
uint256 public rebaseInterval = 1 hours;
uint256 public rebaseBasisPoints = 2; // 0.02%
uint256 public nextRebaseTime = 0;
uint256 public defaultSenderBurnBasisPoints = 0;
uint256 public defaultSenderFundBasisPoints = 0;
uint256 public defaultReceiverBurnBasisPoints = 43; // 0.43%
uint256 public defaultReceiverFundBasisPoints = 7; // 0.07%
uint256 public govHandoverTime;
mapping (address => uint256) public balances;
mapping (address => mapping (address => uint256)) public allowances;
// msg.sender => transfer config
mapping (address => TransferConfig) public transferConfigs;
// balances in safe addresses do not get rebased
mapping (address => bool) public safes;
event Toast(address indexed account, uint256 value, uint256 maxSupply);
event FloorPrice(uint256 capital, uint256 supply);
event Rebase(uint256 normalDivisor, uint256 nextRebaseTime);
event GovChange(address gov);
event CreateSafe(address safe, uint256 balance);
event DestroySafe(address safe, uint256 balance);
event RebaseConfigChange(uint256 rebaseInterval, uint256 rebaseBasisPoints);
event DefaultTransferConfigChange(
uint256 senderBasisPoints,
uint256 senderFundBasisPoints,
uint256 receiverBurnBasisPoints,
uint256 receiverFundBasisPoints
);
event SetTransferConfig(
address indexed msgSender,
uint256 senderBasisPoints,
uint256 senderFundBasisPoints,
uint256 receiverBurnBasisPoints,
uint256 receiverFundBasisPoints
);
event ClearTransferConfig(address indexed msgSender);
modifier onlyGov() {
require(msg.sender == gov, "XVIX: forbidden");
_;
}
// the govHandoverTime should be set to a time after XLGE participants can
// withdraw their funds
modifier onlyAfterHandover() {
require(block.timestamp > govHandoverTime, "XVIX: handover time has not passed");
_;
}
modifier enforceMaxSupply() {
_;
require(totalSupply() <= maxSupply, "XVIX: max supply exceeded");
}
constructor(uint256 _initialSupply, uint256 _maxSupply, uint256 _govHandoverTime) public {
gov = msg.sender;
govHandoverTime = _govHandoverTime;
maxSupply = _maxSupply;
_mint(msg.sender, _initialSupply);
_setNextRebaseTime();
}
function setGov(address _gov) public onlyGov {
gov = _gov;
emit GovChange(_gov);
}
function setWebsite(string memory _website) public onlyGov {
website = _website;
}
function setMinter(address _minter) public onlyGov {
require(minter == address(0), "XVIX: minter already set");
minter = _minter;
}
function setFloor(address _floor) public onlyGov {
require(floor == address(0), "XVIX: floor already set");
floor = _floor;
}
function setDistributor(address _distributor) public onlyGov {
require(distributor == address(0), "XVIX: distributor already set");
distributor = _distributor;
}
function setFund(address _fund) public onlyGov {
fund = _fund;
}
function createSafe(address _account) public onlyGov enforceMaxSupply {
require(!safes[_account], "XVIX: account is already a safe");
safes[_account] = true;
uint256 balance = balances[_account];
_normalSupply = _normalSupply.sub(balance);
uint256 safeBalance = balance.mul(SAFE_DIVISOR).div(normalDivisor);
balances[_account] = safeBalance;
_safeSupply = _safeSupply.add(safeBalance);
emit CreateSafe(_account, balanceOf(_account));
}
// onlyAfterHandover guards against a possible gov attack vector
// since XLGE participants have their funds locked for one month,
// it is possible for gov to create a safe address and keep
// XVIX tokens there while destroying all other safes
// this would raise the value of the tokens kept in the safe address
//
// with the onlyAfterHandover modifier this attack can only be attempted
// after XLGE participants are able to withdraw their funds
// this would make it difficult for the attack to be profitable
function destroySafe(address _account) public onlyGov onlyAfterHandover enforceMaxSupply {
require(safes[_account], "XVIX: account is not a safe");
safes[_account] = false;
uint256 balance = balances[_account];
_safeSupply = _safeSupply.sub(balance);
uint256 normalBalance = balance.mul(normalDivisor).div(SAFE_DIVISOR);
balances[_account] = normalBalance;
_normalSupply = _normalSupply.add(normalBalance);
emit DestroySafe(_account, balanceOf(_account));
}
function setRebaseConfig(
uint256 _rebaseInterval,
uint256 _rebaseBasisPoints
) public onlyGov onlyAfterHandover {
require(_rebaseInterval >= MIN_REBASE_INTERVAL, "XVIX: rebaseInterval below limit");
require(_rebaseInterval <= MAX_REBASE_INTERVAL, "XVIX: rebaseInterval exceeds limit");
require(_rebaseBasisPoints <= MAX_REBASE_BASIS_POINTS, "XVIX: rebaseBasisPoints exceeds limit");
rebaseInterval = _rebaseInterval;
rebaseBasisPoints = _rebaseBasisPoints;
emit RebaseConfigChange(_rebaseInterval, _rebaseBasisPoints);
}
function setDefaultTransferConfig(
uint256 _senderBurnBasisPoints,
uint256 _senderFundBasisPoints,
uint256 _receiverBurnBasisPoints,
uint256 _receiverFundBasisPoints
) public onlyGov onlyAfterHandover {
_validateTransferConfig(
_senderBurnBasisPoints,
_senderFundBasisPoints,
_receiverBurnBasisPoints,
_receiverFundBasisPoints
);
defaultSenderBurnBasisPoints = _senderBurnBasisPoints;
defaultSenderFundBasisPoints = _senderFundBasisPoints;
defaultReceiverBurnBasisPoints = _receiverBurnBasisPoints;
defaultReceiverFundBasisPoints = _receiverFundBasisPoints;
emit DefaultTransferConfigChange(
_senderBurnBasisPoints,
_senderFundBasisPoints,
_receiverBurnBasisPoints,
_receiverFundBasisPoints
);
}
function setTransferConfig(
address _msgSender,
uint256 _senderBurnBasisPoints,
uint256 _senderFundBasisPoints,
uint256 _receiverBurnBasisPoints,
uint256 _receiverFundBasisPoints
) public onlyGov {
require(_msgSender != address(0), "XVIX: cannot set zero address");
_validateTransferConfig(
_senderBurnBasisPoints,
_senderFundBasisPoints,
_receiverBurnBasisPoints,
_receiverFundBasisPoints
);
transferConfigs[_msgSender] = TransferConfig(
true,
_senderBurnBasisPoints,
_senderFundBasisPoints,
_receiverBurnBasisPoints,
_receiverFundBasisPoints
);
emit SetTransferConfig(
_msgSender,
_senderBurnBasisPoints,
_senderFundBasisPoints,
_receiverBurnBasisPoints,
_receiverFundBasisPoints
);
}
function clearTransferConfig(address _msgSender) public onlyGov onlyAfterHandover {
delete transferConfigs[_msgSender];
emit ClearTransferConfig(_msgSender);
}
function rebase() public override returns (bool) {
if (block.timestamp < nextRebaseTime) { return false; }
// calculate the number of intervals that have passed
uint256 timeDiff = block.timestamp.sub(nextRebaseTime);
uint256 intervals = timeDiff.div(rebaseInterval).add(1);
// the multiplier is calculated as (~10000)^intervals
// the max value of intervals is capped at 10 to avoid uint overflow errors
// 2^256 has 77 digits
// 10,000^10 has 40
// MAX_NORMAL_DIVISOR has 23 digits
if (intervals > MAX_INTERVALS_PER_REBASE) {
intervals = MAX_INTERVALS_PER_REBASE;
}
_setNextRebaseTime();
if (rebaseBasisPoints == 0) { return false; }
uint256 multiplier = BASIS_POINTS_DIVISOR.add(rebaseBasisPoints) ** intervals;
uint256 divider = BASIS_POINTS_DIVISOR ** intervals;
uint256 nextDivisor = normalDivisor.mul(multiplier).div(divider);
if (nextDivisor > MAX_NORMAL_DIVISOR) {
return false;
}
normalDivisor = nextDivisor;
emit Rebase(normalDivisor, nextRebaseTime);
return true;
}
function mint(address _account, uint256 _amount) public override returns (bool) {
require(msg.sender == minter, "XVIX: forbidden");
_mint(_account, _amount);
return true;
}
// permanently remove tokens from circulation by reducing maxSupply
function toast(uint256 _amount) public override returns (bool) {
require(msg.sender == distributor, "XVIX: forbidden");
if (_amount == 0) { return false; }
_burn(msg.sender, _amount);
maxSupply = maxSupply.sub(_amount);
emit Toast(msg.sender, _amount, maxSupply);
return true;
}
function burn(address _account, uint256 _amount) public override returns (bool) {
require(msg.sender == floor, "XVIX: forbidden");
_burn(_account, _amount);
return true;
}
function balanceOf(address _account) public view override returns (uint256) {
if (safes[_account]) {
return balances[_account].div(SAFE_DIVISOR);
}
return balances[_account].div(normalDivisor);
}
function transfer(address _recipient, uint256 _amount) public override returns (bool) {
_transfer(msg.sender, _recipient, _amount);
rebase();
return true;
}
function allowance(address _owner, address _spender) public view override returns (uint256) {
return allowances[_owner][_spender];
}
function approve(address _spender, uint256 _amount) public override returns (bool) {
_approve(msg.sender, _spender, _amount);
return true;
}
function transferFrom(address _sender, address _recipient, uint256 _amount) public override returns (bool) {
uint256 nextAllowance = allowances[_sender][msg.sender].sub(_amount, "XVIX: transfer amount exceeds allowance");
_approve(_sender, msg.sender, nextAllowance);
_transfer(_sender, _recipient, _amount);
rebase();
return true;
}
function normalSupply() public view returns (uint256) {
return _normalSupply.div(normalDivisor);
}
function safeSupply() public view returns (uint256) {
return _safeSupply.div(SAFE_DIVISOR);
}
function totalSupply() public view override returns (uint256) {
return normalSupply().add(safeSupply());
}
function _validateTransferConfig(
uint256 _senderBurnBasisPoints,
uint256 _senderFundBasisPoints,
uint256 _receiverBurnBasisPoints,
uint256 _receiverFundBasisPoints
) private pure {
require(_senderBurnBasisPoints <= MAX_BURN_BASIS_POINTS, "XVIX: senderBurnBasisPoints exceeds limit");
require(_senderFundBasisPoints <= MAX_FUND_BASIS_POINTS, "XVIX: senderFundBasisPoints exceeds limit");
require(_receiverBurnBasisPoints <= MAX_BURN_BASIS_POINTS, "XVIX: receiverBurnBasisPoints exceeds limit");
require(_receiverFundBasisPoints <= MAX_FUND_BASIS_POINTS, "XVIX: receiverFundBasisPoints exceeds limit");
}
function _setNextRebaseTime() private {
uint256 roundedTime = block.timestamp.div(rebaseInterval).mul(rebaseInterval);
nextRebaseTime = roundedTime.add(rebaseInterval);
}
function _transfer(address _sender, address _recipient, uint256 _amount) private {
require(_sender != address(0), "XVIX: transfer from the zero address");
require(_recipient != address(0), "XVIX: transfer to the zero address");
(uint256 senderBurn,
uint256 senderFund,
uint256 receiverBurn,
uint256 receiverFund) = _getTransferConfig();
// increase senderAmount based on senderBasisPoints
uint256 senderAmount = _amount;
uint256 senderBasisPoints = senderBurn.add(senderFund);
if (senderBasisPoints > 0) {
uint256 senderTax = _amount.mul(senderBasisPoints).div(BASIS_POINTS_DIVISOR);
senderAmount = senderAmount.add(senderTax);
}
// decrease receiverAmount based on receiverBasisPoints
uint256 receiverAmount = _amount;
uint256 receiverBasisPoints = receiverBurn.add(receiverFund);
if (receiverBasisPoints > 0) {
uint256 receiverTax = _amount.mul(receiverBasisPoints).div(BASIS_POINTS_DIVISOR);
receiverAmount = receiverAmount.sub(receiverTax);
}
_decreaseBalance(_sender, senderAmount);
_increaseBalance(_recipient, receiverAmount);
emit Transfer(_sender, _recipient, receiverAmount);
// increase fund balance based on fundBasisPoints
uint256 fundBasisPoints = senderFund.add(receiverFund);
uint256 fundAmount = _amount.mul(fundBasisPoints).div(BASIS_POINTS_DIVISOR);
if (fundAmount > 0) {
_increaseBalance(fund, fundAmount);
emit Transfer(_sender, fund, fundAmount);
}
// emit burn event
uint256 burnAmount = senderAmount.sub(receiverAmount).sub(fundAmount);
if (burnAmount > 0) {
emit Transfer(_sender, address(0), burnAmount);
}
_emitFloorPrice();
}
function _getTransferConfig() private view returns (uint256, uint256, uint256, uint256) {
uint256 senderBurn = defaultSenderBurnBasisPoints;
uint256 senderFund = defaultSenderFundBasisPoints;
uint256 receiverBurn = defaultReceiverBurnBasisPoints;
uint256 receiverFund = defaultReceiverFundBasisPoints;
TransferConfig memory config = transferConfigs[msg.sender];
if (config.active) {
senderBurn = config.senderBurnBasisPoints;
senderFund = config.senderFundBasisPoints;
receiverBurn = config.receiverBurnBasisPoints;
receiverFund = config.receiverFundBasisPoints;
}
return (senderBurn, senderFund, receiverBurn, receiverFund);
}
function _approve(address _owner, address _spender, uint256 _amount) private {
require(_owner != address(0), "XVIX: approve from the zero address");
require(_spender != address(0), "XVIX: approve to the zero address");
allowances[_owner][_spender] = _amount;
emit Approval(_owner, _spender, _amount);
}
function _mint(address _account, uint256 _amount) private {
require(_account != address(0), "XVIX: mint to the zero address");
if (_amount == 0) { return; }
_increaseBalance(_account, _amount);
emit Transfer(address(0), _account, _amount);
_emitFloorPrice();
}
function _burn(address _account, uint256 _amount) private {
require(_account != address(0), "XVIX: burn from the zero address");
if (_amount == 0) { return; }
_decreaseBalance(_account, _amount);
emit Transfer(_account, address(0), _amount);
_emitFloorPrice();
}
function _increaseBalance(address _account, uint256 _amount) private enforceMaxSupply {
if (_amount == 0) { return; }
if (safes[_account]) {
uint256 safeAmount = _amount.mul(SAFE_DIVISOR);
balances[_account] = balances[_account].add(safeAmount);
_safeSupply = _safeSupply.add(safeAmount);
return;
}
uint256 normalAmount = _amount.mul(normalDivisor);
balances[_account] = balances[_account].add(normalAmount);
_normalSupply = _normalSupply.add(normalAmount);
}
function _decreaseBalance(address _account, uint256 _amount) private {
if (_amount == 0) { return; }
if (safes[_account]) {
uint256 safeAmount = _amount.mul(SAFE_DIVISOR);
balances[_account] = balances[_account].sub(safeAmount, "XVIX: subtraction amount exceeds balance");
_safeSupply = _safeSupply.sub(safeAmount);
return;
}
uint256 normalAmount = _amount.mul(normalDivisor);
balances[_account] = balances[_account].sub(normalAmount, "XVIX: subtraction amount exceeds balance");
_normalSupply = _normalSupply.sub(normalAmount);
}
function _emitFloorPrice() private {
if (_isContract(floor)) {
emit FloorPrice(IFloor(floor).capital(), totalSupply());
}
}
function _isContract(address account) private view returns (bool) {
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
{
"compilationTarget": {
"contracts/XVIX.sol": "XVIX"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"_initialSupply","type":"uint256"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"uint256","name":"_govHandoverTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"}],"name":"ClearTransferConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"safe","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"CreateSafe","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"senderBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"senderFundBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"receiverBurnBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"receiverFundBasisPoints","type":"uint256"}],"name":"DefaultTransferConfigChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"safe","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"DestroySafe","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"capital","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"FloorPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"gov","type":"address"}],"name":"GovChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"normalDivisor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nextRebaseTime","type":"uint256"}],"name":"Rebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rebaseInterval","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rebaseBasisPoints","type":"uint256"}],"name":"RebaseConfigChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":false,"internalType":"uint256","name":"senderBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"senderFundBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"receiverBurnBasisPoints","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"receiverFundBasisPoints","type":"uint256"}],"name":"SetTransferConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"Toast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BASIS_POINTS_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BURN_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FUND_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_INTERVALS_PER_REBASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NORMAL_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REBASE_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REBASE_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_REBASE_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SAFE_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_normalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_safeSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgSender","type":"address"}],"name":"clearTransferConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"createSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultReceiverBurnBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultReceiverFundBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultSenderBurnBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultSenderFundBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"destroySafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"floor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"govHandoverTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextRebaseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"normalDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"normalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebase","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebaseBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safeSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"safes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_senderBurnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"_senderFundBasisPoints","type":"uint256"},{"internalType":"uint256","name":"_receiverBurnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"_receiverFundBasisPoints","type":"uint256"}],"name":"setDefaultTransferConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_distributor","type":"address"}],"name":"setDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_floor","type":"address"}],"name":"setFloor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fund","type":"address"}],"name":"setFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rebaseInterval","type":"uint256"},{"internalType":"uint256","name":"_rebaseBasisPoints","type":"uint256"}],"name":"setRebaseConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgSender","type":"address"},{"internalType":"uint256","name":"_senderBurnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"_senderFundBasisPoints","type":"uint256"},{"internalType":"uint256","name":"_receiverBurnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"_receiverFundBasisPoints","type":"uint256"}],"name":"setTransferConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_website","type":"string"}],"name":"setWebsite","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"toast","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"transferConfigs","outputs":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"senderBurnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"senderFundBasisPoints","type":"uint256"},{"internalType":"uint256","name":"receiverBurnBasisPoints","type":"uint256"},{"internalType":"uint256","name":"receiverFundBasisPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"website","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]