ERC20
This contract is an ERC20 token.
Name
Tribe
Symbol
TRIBE
Decimals
18
Total Supply
1,000,000,000 TRIBE
About
link
description
Tribe (TRIBE) is a cryptocurrency and operates on the Ethereum platform. Tribe has a current supply of 1,000,000,000 with 248,364,400 in circulation. The last known price of Tribe is 0.57530431 USD and is up 0.60 over the last 24 hours. It is currently trading on 12 active market(s) with $1,037,092.04 traded over the last 24 hours. More information can be found at https://fei.money/.
Stats
Public Functions
12
Event Types
5
Code Size
16,254 bytes
Events (5) keyboard_arrow_up
Constants (6) keyboard_arrow_up
State Variables (8) keyboard_arrow_up
Functions
setMinter keyboard_arrow_up
Requirements help
Source Code
function setMinter(address minter_) external {
require(
msg.sender == minter,
"Tribe: only the minter can change the minter address"
);
emit MinterChanged(minter, minter_);
minter = minter_;
}
mint keyboard_arrow_up
Requirements help
Source Code
function mint(address dst, uint256 rawAmount) external {
require(msg.sender == minter, "Tribe: only the minter can mint");
require(dst != address(0), "Tribe: cannot transfer to the zero address");
// mint the amount
uint96 amount = safe96(rawAmount, "Tribe: amount exceeds 96 bits");
uint96 safeSupply = safe96(totalSupply, "Tribe: totalSupply exceeds 96 bits");
totalSupply = add96(safeSupply, amount, "Tribe: totalSupply exceeds 96 bits");
// transfer the amount to the recipient
balances[dst] = add96(
balances[dst],
amount,
"Tribe: transfer amount overflows"
);
emit Transfer(address(0), dst, amount);
// move delegates
_moveDelegates(address(0), delegates[dst], amount);
}
allowance keyboard_arrow_up
approve keyboard_arrow_up
Source Code
function approve(address spender, uint256 rawAmount) external returns (bool) {
uint96 amount;
if (rawAmount == uint256(-1)) {
amount = uint96(-1);
} else {
amount = safe96(rawAmount, "Tribe: amount exceeds 96 bits");
}
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
permit keyboard_arrow_up
Parameters help
Requirements help
Source Code
function permit(
address owner,
address spender,
uint256 rawAmount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
uint96 amount;
if (rawAmount == uint256(-1)) {
amount = uint96(-1);
} else {
amount = safe96(rawAmount, "Tribe: amount exceeds 96 bits");
}
bytes32 domainSeparator = keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name)),
getChainId(),
address(this)
)
);
bytes32 structHash = keccak256(
abi.encode(
PERMIT_TYPEHASH,
owner,
spender,
rawAmount,
nonces[owner]++,
deadline
)
);
bytes32 digest = keccak256(
abi.encodePacked("\x19\x01", domainSeparator, structHash)
);
address signatory = ecrecover(digest, v, r, s);
require(signatory != address(0), "Tribe: invalid signature");
require(signatory == owner, "Tribe: unauthorized");
// solhint-disable-next-line not-rely-on-time
require(block.timestamp <= deadline, "Tribe: signature expired");
allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
balanceOf keyboard_arrow_up
transfer keyboard_arrow_up
Requirements help
Source Code
function transfer(address dst, uint256 rawAmount) external returns (bool) {
uint96 amount = safe96(rawAmount, "Tribe: amount exceeds 96 bits");
_transferTokens(msg.sender, dst, amount);
return true;
}
transferFrom keyboard_arrow_up
Requirements help
Source Code
function transferFrom(
address src,
address dst,
uint256 rawAmount
) external returns (bool) {
address spender = msg.sender;
uint96 spenderAllowance = allowances[src][spender];
uint96 amount = safe96(rawAmount, "Tribe: amount exceeds 96 bits");
if (spender != src && spenderAllowance != uint96(-1)) {
uint96 newAllowance = sub96(
spenderAllowance,
amount,
"Tribe: transfer amount exceeds spender allowance"
);
allowances[src][spender] = newAllowance;
emit Approval(src, spender, newAllowance);
}
_transferTokens(src, dst, amount);
return true;
}
delegate keyboard_arrow_up
delegateBySig keyboard_arrow_up
Parameters help
Requirements help
Source Code
function delegateBySig(
address delegatee,
uint256 nonce,
uint256 expiry,
uint8 v,
bytes32 r,
bytes32 s
) public {
bytes32 domainSeparator = keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name)),
getChainId(),
address(this)
)
);
bytes32 structHash = keccak256(
abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry)
);
bytes32 digest = keccak256(
abi.encodePacked("\x19\x01", domainSeparator, structHash)
);
address signatory = ecrecover(digest, v, r, s);
require(signatory != address(0), "Tribe: invalid signature");
require(nonce == nonces[signatory]++, "Tribe: invalid nonce");
// solhint-disable-next-line not-rely-on-time
require(block.timestamp <= expiry, "Tribe: signature expired");
return _delegate(signatory, delegatee);
}
getCurrentVotes keyboard_arrow_up
Source Code
function getCurrentVotes(address account) external view returns (uint96) {
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}
getPriorVotes keyboard_arrow_up
Requirements help
Source Code
function getPriorVotes(address account, uint256 blockNumber)
public
view
returns (uint96)
{
require(blockNumber < block.number, "Tribe: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints == 0) {
return 0;
}
// First check most recent balance
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints - 1].votes;
}
// Next check implicit zero balance
if (checkpoints[account][0].fromBlock > blockNumber) {
return 0;
}
uint32 lower = 0;
uint32 upper = nCheckpoints - 1;
while (upper > lower) {
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
Checkpoint memory cp = checkpoints[account][center];
if (cp.fromBlock == blockNumber) {
return cp.votes;
} else if (cp.fromBlock < blockNumber) {
lower = center;
} else {
upper = center - 1;
}
}
return checkpoints[account][lower].votes;
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal Tribe._delegate keyboard_arrow_up
Source Code
function _delegate(address delegator, address delegatee) internal {
address currentDelegate = delegates[delegator];
uint96 delegatorBalance = balances[delegator];
delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
internal Tribe._transferTokens keyboard_arrow_up
Requirements help
Source Code
function _transferTokens(
address src,
address dst,
uint96 amount
) internal {
require(src != address(0), "Tribe: cannot transfer from the zero address");
require(dst != address(0), "Tribe: cannot transfer to the zero address");
balances[src] = sub96(
balances[src],
amount,
"Tribe: transfer amount exceeds balance"
);
balances[dst] = add96(
balances[dst],
amount,
"Tribe: transfer amount overflows"
);
emit Transfer(src, dst, amount);
_moveDelegates(delegates[src], delegates[dst], amount);
}
internal Tribe._moveDelegates keyboard_arrow_up
Source Code
function _moveDelegates(
address srcRep,
address dstRep,
uint96 amount
) internal {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
uint32 srcRepNum = numCheckpoints[srcRep];
uint96 srcRepOld = srcRepNum > 0
? checkpoints[srcRep][srcRepNum - 1].votes
: 0;
uint96 srcRepNew = sub96(
srcRepOld,
amount,
"Tribe: vote amount underflows"
);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep != address(0)) {
uint32 dstRepNum = numCheckpoints[dstRep];
uint96 dstRepOld = dstRepNum > 0
? checkpoints[dstRep][dstRepNum - 1].votes
: 0;
uint96 dstRepNew = add96(
dstRepOld,
amount,
"Tribe: vote amount overflows"
);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
internal Tribe._writeCheckpoint keyboard_arrow_up
Parameters help
Source Code
function _writeCheckpoint(
address delegatee,
uint32 nCheckpoints,
uint96 oldVotes,
uint96 newVotes
) internal {
uint32 blockNumber = safe32(
block.number,
"Tribe: block number exceeds 32 bits"
);
if (
nCheckpoints > 0 &&
checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber
) {
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
} else {
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
numCheckpoints[delegatee] = nCheckpoints + 1;
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
internal Tribe.safe32 keyboard_arrow_up
Source Code
function safe32(uint256 n, string memory errorMessage)
internal
pure
returns (uint32)
{
require(n < 2**32, errorMessage);
return uint32(n);
}
internal Tribe.safe96 keyboard_arrow_up
Source Code
function safe96(uint256 n, string memory errorMessage)
internal
pure
returns (uint96)
{
require(n < 2**96, errorMessage);
return uint96(n);
}
internal Tribe.add96 keyboard_arrow_up
Source Code
function add96(
uint96 a,
uint96 b,
string memory errorMessage
) internal pure returns (uint96) {
uint96 c = a + b;
require(c >= a, errorMessage);
return c;
}
internal Tribe.sub96 keyboard_arrow_up
Source Code
function sub96(
uint96 a,
uint96 b,
string memory errorMessage
) internal pure returns (uint96) {
require(b <= a, errorMessage);
return a - b;
}