Address Contract Verified
Address
0xf829d7014Db17D6DCe448bE958c7e4983cdb1F77
Balance
0 ETH
Nonce
1
Code Size
8298 bytes
Creator
0x7d3047D0...9F74 at tx 0xcd124ead...41114b
Indexed Transactions
0
Contract Bytecode
8298 bytes
0x608060405234801561001057600080fd5b50600436106101375760003560e01c8063485cc955116100b85780639358928b1161007c5780639358928b1461039057806395d89b41146103ae578063a457c2d7146103cc578063a9059cbb146103fc578063dd62ed3e1461042c578063ee99205c1461045c57610137565b8063485cc955146102c057806361d027b3146102dc57806370a08231146102fa57806373c69eb71461032a5780637965d56d1461036057610137565b806323b872dd116100ff57806323b872dd146102085780632986c0e514610238578063313ce56714610256578063395093511461027457806340a5737f146102a457610137565b8063058ecdb41461013c57806306fdde031461016c578063095ea7b31461018a57806318160ddd146101ba5780631bd39674146101d8575b600080fd5b610156600480360381019061015191906117be565b61047a565b604051610163919061180d565b60405180910390f35b6101746106ae565b60405161018191906118b8565b60405180910390f35b6101a4600480360381019061019f9190611938565b610740565b6040516101b19190611993565b60405180910390f35b6101c2610757565b6040516101cf919061180d565b60405180910390f35b6101f260048036038101906101ed91906119ae565b610761565b6040516101ff919061180d565b60405180910390f35b610222600480360381019061021d91906119db565b610778565b60405161022f9190611993565b60405180910390f35b610240610afd565b60405161024d919061180d565b60405180910390f35b61025e610b0f565b60405161026b9190611a4a565b60405180910390f35b61028e60048036038101906102899190611938565b610b18565b60405161029b9190611993565b60405180910390f35b6102be60048036038101906102b991906119ae565b610bb6565b005b6102da60048036038101906102d59190611a65565b610c9d565b005b6102e4611079565b6040516102f19190611ab4565b60405180910390f35b610314600480360381019061030f9190611acf565b61109f565b604051610321919061180d565b60405180910390f35b610344600480360381019061033f91906119ae565b6110f5565b6040516103579796959493929190611afc565b60405180910390f35b61037a600480360381019061037591906119ae565b611147565b604051610387919061180d565b60405180910390f35b61039861115e565b6040516103a5919061180d565b60405180910390f35b6103b661119d565b6040516103c391906118b8565b60405180910390f35b6103e660048036038101906103e19190611938565b61122f565b6040516103f39190611993565b60405180910390f35b61041660048036038101906104119190611938565b6112eb565b6040516104239190611993565b60405180910390f35b61044660048036038101906104419190611a65565b61148a565b604051610453919061180d565b60405180910390f35b610464611511565b6040516104719190611ab4565b60405180910390f35b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050390611bdd565b60405180910390fd5b60008061051761115e565b9050600085036105a957837f0417b340e646d4be71f9b2da63b5c3c69bc9cfa069f0e0db4756271886130bf4600754604051610553919061180d565b60405180910390a2837f6012dbce857565c4a40974aa5de8373a761fc429077ef0c8c8611d1e20d63fb26000610587610afd565b604051610595929190611c42565b60405180910390a2600754925050506106a8565b60008111156105d25780600754866105c19190611c9a565b6105cb9190611d0b565b91506105d6565b8491505b816007546105e49190611d3c565b6007819055506000196fffffffffffffffffffffffffffffffff166007541115610624576000196fffffffffffffffffffffffffffffffff166007819055505b6007546611c37937e080007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61065a9190611d70565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106859190611da1565b61068f9190611d0b565b600a819055506106a0818686611537565b600754925050505b92915050565b6060600380546106bd90611e04565b80601f01602080910402602001604051908101604052809291908181526020018280546106e990611e04565b80156107365780601f1061070b57610100808354040283529160200191610736565b820191906000526020600020905b81548152906001019060200180831161071957829003601f168201915b5050505050905090565b600061074d338484611698565b6001905092915050565b6000600254905090565b6000600a54826107719190611c9a565b9050919050565b600081600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546108029190611da1565b600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600c60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460405161095b919061180d565b60405180910390a3600061096e83610761565b905080600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546109bb9190611da1565b600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a499190611d3c565b600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ae9919061180d565b60405180910390a360019150509392505050565b6000610b0a600654611147565b905090565b60006009905090565b6000610bac338484600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610ba79190611d3c565b611698565b6001905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3d90611ea7565b60405180910390fd5b600060065414610c8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8290611f13565b60405180910390fd5b610c9481610761565b60068190555050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2490611ea7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9390611f7f565b60405180910390fd5b81600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506611c37937e080007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e109190611d70565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610e3b9190611da1565b600b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0690611feb565b60405180910390fd5b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600754604051610fd2919061180d565b60405180910390a37f817c653428858ed536dc085c5d8273734c517b55de44b55f5c5877a75e3373a1600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405161102b9190611ab4565b60405180910390a16000600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a54600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110ee9190611d0b565b9050919050565b6009818154811061110557600080fd5b90600052602060002090600702016000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b6000600a54826111579190611d0b565b9050919050565b600061118b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661109f565b6007546111989190611da1565b905090565b6060600480546111ac90611e04565b80601f01602080910402602001604051908101604052809291908181526020018280546111d890611e04565b80156112255780601f106111fa57610100808354040283529160200191611225565b820191906000526020600020905b81548152906001019060200180831161120857829003601f168201915b5050505050905090565b600080600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508083106112c9576112c433856000611698565b6112e0565b6112df338585846112da9190611da1565b611698565b5b600191505092915050565b600080600a54836112fc9190611c9a565b905080600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113499190611da1565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546113d79190611d3c565b600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051611477919061180d565b60405180910390a3600191505092915050565b6000600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000808411156115635783670de0b6b3a7640000846115569190611c9a565b6115609190611d0b565b90505b60096040518060e0016040528084815260200183815260200186815260200161158a61115e565b815260200185815260200161159d610afd565b8152602001438152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601555050817f0417b340e646d4be71f9b2da63b5c3c69bc9cfa069f0e0db4756271886130bf4600754604051611649919061180d565b60405180910390a2817f6012dbce857565c4a40974aa5de8373a761fc429077ef0c8c8611d1e20d63fb28261167c610afd565b60405161168a92919061200b565b60405180910390a250505050565b80600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611776919061180d565b60405180910390a3505050565b600080fd5b6000819050919050565b61179b81611788565b81146117a657600080fd5b50565b6000813590506117b881611792565b92915050565b600080604083850312156117d5576117d4611783565b5b60006117e3858286016117a9565b92505060206117f4858286016117a9565b9150509250929050565b61180781611788565b82525050565b600060208201905061182260008301846117fe565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611862578082015181840152602081019050611847565b60008484015250505050565b6000601f19601f8301169050919050565b600061188a82611828565b6118948185611833565b93506118a4818560208601611844565b6118ad8161186e565b840191505092915050565b600060208201905081810360008301526118d2818461187f565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611905826118da565b9050919050565b611915816118fa565b811461192057600080fd5b50565b6000813590506119328161190c565b92915050565b6000806040838503121561194f5761194e611783565b5b600061195d85828601611923565b925050602061196e858286016117a9565b9150509250929050565b60008115159050919050565b61198d81611978565b82525050565b60006020820190506119a86000830184611984565b92915050565b6000602082840312156119c4576119c3611783565b5b60006119d2848285016117a9565b91505092915050565b6000806000606084860312156119f4576119f3611783565b5b6000611a0286828701611923565b9350506020611a1386828701611923565b9250506040611a24868287016117a9565b9150509250925092565b600060ff82169050919050565b611a4481611a2e565b82525050565b6000602082019050611a5f6000830184611a3b565b92915050565b60008060408385031215611a7c57611a7b611783565b5b6000611a8a85828601611923565b9250506020611a9b85828601611923565b9150509250929050565b611aae816118fa565b82525050565b6000602082019050611ac96000830184611aa5565b92915050565b600060208284031215611ae557611ae4611783565b5b6000611af384828501611923565b91505092915050565b600060e082019050611b11600083018a6117fe565b611b1e60208301896117fe565b611b2b60408301886117fe565b611b3860608301876117fe565b611b4560808301866117fe565b611b5260a08301856117fe565b611b5f60c08301846117fe565b98975050505050505050565b7f5374616b696e67436f6e74726163743a202063616c6c206973206e6f7420737460008201527f616b696e6720636f6e7472616374000000000000000000000000000000000000602082015250565b6000611bc7602e83611833565b9150611bd282611b6b565b604082019050919050565b60006020820190508181036000830152611bf681611bba565b9050919050565b6000819050919050565b6000819050919050565b6000611c2c611c27611c2284611bfd565b611c07565b611788565b9050919050565b611c3c81611c11565b82525050565b6000604082019050611c576000830185611c33565b611c6460208301846117fe565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611ca582611788565b9150611cb083611788565b9250828202611cbe81611788565b91508282048414831517611cd557611cd4611c6b565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000611d1682611788565b9150611d2183611788565b925082611d3157611d30611cdc565b5b828204905092915050565b6000611d4782611788565b9150611d5283611788565b9250828201905080821115611d6a57611d69611c6b565b5b92915050565b6000611d7b82611788565b9150611d8683611788565b925082611d9657611d95611cdc565b5b828206905092915050565b6000611dac82611788565b9150611db783611788565b9250828203905081811115611dcf57611dce611c6b565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611e1c57607f821691505b602082108103611e2f57611e2e611dd5565b5b50919050565b7f496e697469616c697a65723a202063616c6c6572206973206e6f7420696e697460008201527f69616c697a657200000000000000000000000000000000000000000000000000602082015250565b6000611e91602783611833565b9150611e9c82611e35565b604082019050919050565b60006020820190508181036000830152611ec081611e84565b9050919050565b7f43616e6e6f742073657420494e44455820616761696e00000000000000000000600082015250565b6000611efd601683611833565b9150611f0882611ec7565b602082019050919050565b60006020820190508181036000830152611f2c81611ef0565b9050919050565b7f5a65726f20616464726573733a205374616b696e670000000000000000000000600082015250565b6000611f69601583611833565b9150611f7482611f33565b602082019050919050565b60006020820190508181036000830152611f9881611f5c565b9050919050565b7f5a65726f20616464726573733a20547265617375727900000000000000000000600082015250565b6000611fd5601683611833565b9150611fe082611f9f565b602082019050919050565b6000602082019050818103600083015261200481611fc8565b9050919050565b600060408201905061202060008301856117fe565b61202d60208301846117fe565b939250505056fea26469706673582212201e11c74329ef0d8d7b3b172a2668f0189a4948bfc0cc70b1496ac83a2494fe0e64736f6c63430008130033
Verified Source Code Full Match
Compiler: v0.8.19+commit.7dd6d404
EVM: paris
Optimization: No
sHATE.sol 247 lines
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../interface/IsHATE.sol";
import "../interface/IStaking.sol";
contract sHATE is IsHATE, ERC20 {
/* ========== EVENTS ========== */
event LogSupply(uint256 indexed epoch, uint256 totalSupply);
event LogRebase(uint256 indexed epoch, uint256 rebase, uint256 index);
event LogStakingContractUpdated(address stakingContract);
/* ========== MODIFIERS ========== */
modifier onlyStakingContract() {
require(msg.sender == stakingContract, "StakingContract: call is not staking contract");
_;
}
/* ========== DATA STRUCTURES ========== */
struct Rebase {
uint256 epoch;
uint256 rebase; // 18 decimals
uint256 totalStakedBefore;
uint256 totalStakedAfter;
uint256 amountRebased;
uint256 index;
uint256 blockNumberOccured;
}
/* ========== STATE VARIABLES ========== */
address internal initializer;
uint256 internal INDEX; // Index Gons - tracks rebase growth
uint256 internal _totalSupply;
address public stakingContract; // balance used to calc rebase
Rebase[] public rebases; // past rebase data
uint256 private constant MAX_UINT256 = type(uint256).max;
uint256 private constant INITIAL_FRAGMENTS_SUPPLY = 5_000_000 * 10**9;
// TOTAL_GONS is a multiple of INITIAL_FRAGMENTS_SUPPLY so that _gonsPerFragment is an integer.
// Use the highest value that fits in a uint256 for max granularity.
uint256 private constant TOTAL_GONS = MAX_UINT256 - (MAX_UINT256 % INITIAL_FRAGMENTS_SUPPLY);
// MAX_SUPPLY = maximum integer < (sqrt(4*TOTAL_GONS + 1) - 1) / 2
uint256 private constant MAX_SUPPLY = ~uint128(0); // (2^128) - 1
uint256 private _gonsPerFragment;
mapping(address => uint256) private _gonBalances;
mapping(address => mapping(address => uint256)) private _allowedValue;
address public treasury;
/* ========== CONSTRUCTOR ========== */
constructor() ERC20("Staked HATE", "sHATE") {
initializer = msg.sender;
_totalSupply = INITIAL_FRAGMENTS_SUPPLY;
_gonsPerFragment = TOTAL_GONS / _totalSupply;
}
function decimals() public view virtual override returns (uint8) {
return 9;
}
/* ========== INITIALIZATION ========== */
function setIndex(uint256 _index) external {
require(msg.sender == initializer, "Initializer: caller is not initializer");
require(INDEX == 0, "Cannot set INDEX again");
INDEX = gonsForBalance(_index);
}
function initialize(address _stakingContract, address _treasury) external {
require(msg.sender == initializer, "Initializer: caller is not initializer");
require(_stakingContract != address(0), "Zero address: Staking");
stakingContract = _stakingContract;
_gonBalances[stakingContract] = TOTAL_GONS;
require(_treasury != address(0), "Zero address: Treasury");
treasury = _treasury;
emit Transfer(address(0x0), stakingContract, _totalSupply);
emit LogStakingContractUpdated(stakingContract);
initializer = address(0);
}
/* ========== REBASE ========== */
/**
@notice increases sHATE supply
@param amount_ uint256
@return uint256
*/
function rebase(uint256 amount_, uint256 epoch_) public override onlyStakingContract returns (uint256) {
uint256 rebaseAmount;
uint256 circulatingSupply_ = circulatingSupply();
if (amount_ == 0) {
emit LogSupply(epoch_, _totalSupply);
emit LogRebase(epoch_, 0, index());
return _totalSupply;
} else if (circulatingSupply_ > 0) {
rebaseAmount = amount_ * _totalSupply / circulatingSupply_;
} else {
rebaseAmount = amount_;
}
_totalSupply = _totalSupply + rebaseAmount;
if (_totalSupply > MAX_SUPPLY) {
_totalSupply = MAX_SUPPLY;
}
_gonsPerFragment = TOTAL_GONS / _totalSupply;
_storeRebase(circulatingSupply_, amount_, epoch_);
return _totalSupply;
}
/**
@notice emits event with data about rebase
@param previousCirculating_ uint
@param profit_ uint
@param epoch_ uint
*/
function _storeRebase(
uint256 previousCirculating_,
uint256 profit_,
uint256 epoch_
) internal {
uint256 rebasePercent;
if (previousCirculating_ > 0) rebasePercent = profit_ * 1e18 / previousCirculating_;
rebases.push(
Rebase({
epoch: epoch_,
rebase: rebasePercent, // 18 decimals
totalStakedBefore: previousCirculating_,
totalStakedAfter: circulatingSupply(),
amountRebased: profit_,
index: index(),
blockNumberOccured: block.number
})
);
emit LogSupply(epoch_, _totalSupply);
emit LogRebase(epoch_, rebasePercent, index());
}
/* ========== MUTATIVE FUNCTIONS =========== */
function transfer(address to, uint256 value) public override(IERC20, ERC20) returns (bool) {
uint256 gonValue = value * _gonsPerFragment;
_gonBalances[msg.sender] = _gonBalances[msg.sender] - gonValue;
_gonBalances[to] = _gonBalances[to] + gonValue;
emit Transfer(msg.sender, to, value);
return true;
}
function transferFrom(
address from,
address to,
uint256 value
) public override(IERC20, ERC20) returns (bool) {
_allowedValue[from][msg.sender] = _allowedValue[from][msg.sender] - value;
emit Approval(from, msg.sender, _allowedValue[from][msg.sender]);
uint256 gonValue = gonsForBalance(value);
_gonBalances[from] = _gonBalances[from] - gonValue;
_gonBalances[to] = _gonBalances[to] + gonValue;
emit Transfer(from, to, value);
return true;
}
function approve(address spender, uint256 value) public override(IERC20, ERC20) returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public override returns (bool) {
_approve(msg.sender, spender, _allowedValue[msg.sender][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public override returns (bool) {
uint256 oldValue = _allowedValue[msg.sender][spender];
if (subtractedValue >= oldValue) {
_approve(msg.sender, spender, 0);
} else {
_approve(msg.sender, spender, oldValue - subtractedValue);
}
return true;
}
/* ========== INTERNAL FUNCTIONS ========== */
function _approve(
address owner,
address spender,
uint256 value
) internal virtual override {
_allowedValue[owner][spender] = value;
emit Approval(owner, spender, value);
}
/* ========== VIEW FUNCTIONS ========== */
function balanceOf(address who) public view override(IERC20, ERC20) returns (uint256) {
return _gonBalances[who] / _gonsPerFragment;
}
function gonsForBalance(uint256 amount) public view override returns (uint256) {
return amount * _gonsPerFragment;
}
function balanceForGons(uint256 gons) public view override returns (uint256) {
return gons / _gonsPerFragment;
}
// Staking contract holds excess sHATE
function circulatingSupply() public view override returns (uint256) {
return
_totalSupply - balanceOf(stakingContract);
}
function index() public view override returns (uint256) {
return balanceForGons(INDEX);
}
function allowance(address owner_, address spender) public view override(IERC20, ERC20) returns (uint256) {
return _allowedValue[owner_][spender];
}
}
IsHATE.sol 16 lines
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IsHATE is IERC20 {
function rebase(uint256 amount_, uint epoch_) external returns (uint256);
function circulatingSupply() external view returns (uint256);
function gonsForBalance(uint amount) external view returns (uint);
function balanceForGons(uint gons) external view returns (uint);
function index() external view returns (uint);
}
IStaking.sol 18 lines
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.19;
interface IStaking {
function stake(
address _to,
uint256 _amount
) external;
function unstake(
address _to,
uint256 _amount
) external;
function rebase() external;
function index() external view returns (uint256);
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
ERC20.sol 389 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
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);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}
IERC20Metadata.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
Read Contract
allowance 0xdd62ed3e → uint256
balanceForGons 0x7965d56d → uint256
balanceOf 0x70a08231 → uint256
circulatingSupply 0x9358928b → uint256
decimals 0x313ce567 → uint8
gonsForBalance 0x1bd39674 → uint256
index 0x2986c0e5 → uint256
name 0x06fdde03 → string
rebases 0x73c69eb7 → uint256, uint256, uint256, uint256, uint256, uint256, uint256
stakingContract 0xee99205c → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
treasury 0x61d027b3 → address
Write Contract 8 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address spender
uint256 value
returns: bool
decreaseAllowance 0xa457c2d7
address spender
uint256 subtractedValue
returns: bool
increaseAllowance 0x39509351
address spender
uint256 addedValue
returns: bool
initialize 0x485cc955
address _stakingContract
address _treasury
rebase 0x058ecdb4
uint256 amount_
uint256 epoch_
returns: uint256
setIndex 0x40a5737f
uint256 _index
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
Recent Transactions
No transactions found for this address