Fantom Token
ERC20
This contract is an ERC20 token.
Name
Fantom Token
Symbol
FTM
Decimals
18
Total Supply
2,132,239,133 FTM
About
Stats
Public Functions
36
Event Types
13
Code Size
20,626 bytes
Events (13) keyboard_arrow_up
Constants (10) keyboard_arrow_up
State Variables (24) keyboard_arrow_up
Functions
transferOwnership keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function transferOwnership(address _newOwner) public onlyOwner {
require(_newOwner != address(0x0));
emit OwnershipTransferProposed(owner, _newOwner);
newOwner = _newOwner;
}
acceptOwnership keyboard_arrow_up
addAdmin keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function addAdmin(address _a) public onlyOwner {
require(isAdmin[_a] == false);
isAdmin[_a] = true;
emit AdminChange(_a, true);
}
removeAdmin keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function removeAdmin(address _a) public onlyOwner {
require(isAdmin[_a] == true);
isAdmin[_a] = false;
emit AdminChange(_a, false);
}
setDateMainStart keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
checkDateOrder checks for the following:
Requirements help
Source Code
function setDateMainStart(uint256 _unixts) public onlyOwner checkDateOrder {
require(now < _unixts && now < dateMainStart);
dateMainStart = _unixts;
emit IcoDateUpdated(1, _unixts);
}
setDateMainEnd keyboard_arrow_up
isMainFirstDay keyboard_arrow_up
isMain keyboard_arrow_up
totalSupply keyboard_arrow_up
balanceOf keyboard_arrow_up
transfer keyboard_arrow_up
Requirements help
tokensTradeable must be true
_amount
must be less than or equal to
the result of calling unlockedTokensInternal with the sender's address
Source Code
function transfer(address _to, uint256 _amount) public returns (bool success) {
require(tokensTradeable);
require(_amount <= unlockedTokensInternal(msg.sender));
return super.transfer(_to, _amount);
}
transferFrom keyboard_arrow_up
Requirements help
tokensTradeable must be true
Source Code
function transferFrom(
address _from,
address _to,
uint256 _amount
) public returns (bool success) {
require(tokensTradeable);
require(_amount <= unlockedTokensInternal(_from));
return super.transferFrom(_from, _to, _amount);
}
approve keyboard_arrow_up
Source Code
function approve(address _spender, uint256 _amount) public returns (bool) {
allowed[msg.sender][_spender] = _amount;
emit Approval(msg.sender, _spender, _amount);
return true;
}
allowance keyboard_arrow_up
lockedTokens keyboard_arrow_up
unlockedTokens keyboard_arrow_up
isAvailableLockSlot keyboard_arrow_up
Source Code
function isAvailableLockSlot(address _account, uint256 _term)
public
view
returns (bool)
{
if (!mayHaveLockedTokens[_account]) return true;
if (_term < now) return true;
uint256[LOCK_SLOTS] storage term = lockTerm[_account];
for (uint256 i; i < LOCK_SLOTS; i++) {
if (term[i] < now || term[i] == _term) return true;
}
return false;
}
setWallet keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function setWallet(address _wallet) public onlyOwner {
require(_wallet != address(0x0));
wallet = _wallet;
emit WalletUpdated(_wallet);
}
constructor keyboard_arrow_up
availableToMint keyboard_arrow_up
firstDayTokenLimit keyboard_arrow_up
ethToTokens keyboard_arrow_up
tokensToEth keyboard_arrow_up
addToWhitelist keyboard_arrow_up
addToWhitelistMultiple keyboard_arrow_up
Modifiers help
onlyAdmin checks for the following:
Source Code
function addToWhitelistMultiple(address[] _addresses) public onlyAdmin {
for (uint256 i; i < _addresses.length; i++) {
pWhitelist(_addresses[i]);
}
}
updateTokensPerEth keyboard_arrow_up
makeTradeable keyboard_arrow_up
Parameters help
This function has no parameters.
Requirements help
One or more of the following:
-
now
must be greater than
dateMainEnd + 20 weeks
- OR
owner
must be equal to
the sender's address
Source Code
function makeTradeable() public {
require(msg.sender == owner || now > dateMainEnd + 20 weeks);
tokensTradeable = true;
}
openMigrationPhase keyboard_arrow_up
mintTokens keyboard_arrow_up
mintTokensMultiple keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Requirements help
Source Code
function mintTokensMultiple(
uint256 _mint_type,
address[] _accounts,
uint256[] _tokens
) public onlyOwner {
require(_accounts.length == _tokens.length);
for (uint256 i; i < _accounts.length; i++) {
pMintTokens(_mint_type, _accounts[i], _tokens[i], 0);
}
}
mintTokensLocked keyboard_arrow_up
mintTokensLockedMultiple keyboard_arrow_up
Parameters help
Modifiers help
onlyOwner checks for the following:
Requirements help
Source Code
function mintTokensLockedMultiple(
uint256 _mint_type,
address[] _accounts,
uint256[] _tokens,
uint256[] _terms
) public onlyOwner {
require(_accounts.length == _tokens.length);
require(_accounts.length == _terms.length);
for (uint256 i; i < _accounts.length; i++) {
pMintTokens(_mint_type, _accounts[i], _tokens[i], _terms[i]);
}
}
requestTokenExchangeMax keyboard_arrow_up
Parameters help
This function has no parameters.
Requirements help
isMigrationPhaseOpen must be true
the result of calling unlockedTokensInternal with the sender's address
must be less than or equal to
the result of calling unlockedTokensInternal with the sender's address
Source Code
function requestTokenExchangeMax() public {
requestTokenExchange(unlockedTokensInternal(msg.sender));
}
requestTokenExchange keyboard_arrow_up
Requirements help
isMigrationPhaseOpen must be true
the result of calling unlockedTokensInternal with the sender's address
must be less than or equal to
the result of calling unlockedTokensInternal with the sender's address
Source Code
function requestTokenExchange(uint256 _tokens) public {
require(isMigrationPhaseOpen);
require(_tokens > 0 && _tokens <= unlockedTokensInternal(msg.sender));
balances[msg.sender] = balances[msg.sender].sub(_tokens);
tokensIssuedTotal = tokensIssuedTotal.sub(_tokens);
emit Transfer(msg.sender, 0x0, _tokens);
emit TokenExchangeRequested(msg.sender, _tokens);
}
transferAnyERC20Token keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
Source Code
function transferAnyERC20Token(address _token_address, uint256 _amount)
public
onlyOwner
returns (bool success)
{
return ERC20Interface(_token_address).transfer(owner, _amount);
}
transferMultiple keyboard_arrow_up
Requirements help
Source Code
function transferMultiple(address[] _addresses, uint256[] _amounts) external {
require(_addresses.length <= 100);
require(_addresses.length == _amounts.length);
// do the transfers
for (uint256 j; j < _addresses.length; j++) {
transfer(_addresses[j], _amounts[j]);
}
}
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 FantomToken.pWhitelist keyboard_arrow_up
Source Code
function pWhitelist(address _account) internal {
if (whitelist[_account]) return;
whitelist[_account] = true;
numberWhitelisted = numberWhitelisted.add(1);
emit Whitelisted(_account, numberWhitelisted);
}
internal FantomToken.pMintTokens keyboard_arrow_up
Parameters help
Requirements help
Source Code
function pMintTokens(
uint256 _mint_type,
address _account,
uint256 _tokens,
uint256 _term
) private {
require(whitelist[_account]);
require(_account != 0x0);
require(_tokens > 0);
require(_tokens <= availableToMint(), "not enough tokens available to mint");
require(
_term == 0 || _term > now,
"either without lock term, or lock term must be in the future"
);
// register locked tokens (will throw if no slot is found)
if (_term > 0) registerLockedTokens(_account, _tokens, _term);
// update
balances[_account] = balances[_account].add(_tokens);
balancesMinted[_account] = balancesMinted[_account].add(_tokens);
balancesMintedByType[_account][_mint_type] = balancesMintedByType[_account][
_mint_type
]
.add(_tokens);
tokensMinted = tokensMinted.add(_tokens);
tokensIssuedTotal = tokensIssuedTotal.add(_tokens);
// log event
emit Transfer(0x0, _account, _tokens);
emit TokensMinted(_mint_type, _account, _tokens, _term);
}
internal FantomToken.buyTokens keyboard_arrow_up
Parameters help
This function has no parameters.
Requirements help
null
Source Code
function buyTokens() private {
require(isMain());
require(msg.value >= MINIMUM_CONTRIBUTION);
require(whitelist[msg.sender]);
uint256 tokens_available = TOKEN_MAIN_CAP.sub(tokensMain);
// adjust tokens_available on first day, if necessary
if (isMainFirstDay()) {
uint256 tokens_available_first_day = firstDayTokenLimit().sub(
balancesMain[msg.sender]
);
if (tokens_available_first_day < tokens_available) {
tokens_available = tokens_available_first_day;
}
}
require(tokens_available > 0);
uint256 tokens_requested = ethToTokens(msg.value);
uint256 tokens_issued = tokens_requested;
uint256 eth_contributed = msg.value;
uint256 eth_returned;
if (tokens_requested > tokens_available) {
tokens_issued = tokens_available;
eth_returned = tokensToEth(tokens_requested.sub(tokens_available));
eth_contributed = msg.value.sub(eth_returned);
}
balances[msg.sender] = balances[msg.sender].add(tokens_issued);
balancesMain[msg.sender] = balancesMain[msg.sender].add(tokens_issued);
tokensMain = tokensMain.add(tokens_issued);
tokensIssuedTotal = tokensIssuedTotal.add(tokens_issued);
ethContributed[msg.sender] = ethContributed[msg.sender].add(eth_contributed);
totalEthContributed = totalEthContributed.add(eth_contributed);
// ether transfers
if (eth_returned > 0) msg.sender.transfer(eth_returned);
wallet.transfer(eth_contributed);
// log
emit Transfer(0x0, msg.sender, tokens_issued);
emit RegisterContribution(
msg.sender,
tokens_issued,
eth_contributed,
eth_returned
);
}
internal LockSlots.registerLockedTokens keyboard_arrow_up
Source Code
function registerLockedTokens(
address _account,
uint256 _tokens,
uint256 _term
) internal returns (uint256 idx) {
require(_term > now, "lock term must be in the future");
// find a slot (clean up while doing this)
// use either the existing slot with the exact same term,
// of which there can be at most one, or the first empty slot
idx = 9999;
uint256[LOCK_SLOTS] storage term = lockTerm[_account];
uint256[LOCK_SLOTS] storage amnt = lockAmnt[_account];
for (uint256 i; i < LOCK_SLOTS; i++) {
if (term[i] < now) {
term[i] = 0;
amnt[i] = 0;
if (idx == 9999) idx = i;
}
if (term[i] == _term) idx = i;
}
// fail if no slot was found
require(idx != 9999, "registerLockedTokens: no available slot found");
// register locked tokens
if (term[idx] == 0) term[idx] = _term;
amnt[idx] = amnt[idx].add(_tokens);
mayHaveLockedTokens[_account] = true;
emit RegisteredLockedTokens(_account, idx, _tokens, _term);
}
internal LockSlots.unlockedTokensInternal keyboard_arrow_up
Source Code
function unlockedTokensInternal(address _account) internal returns (uint256) {
// updates mayHaveLockedTokens if necessary
if (!mayHaveLockedTokens[_account]) return balances[_account];
uint256 locked = pNumberOfLockedTokens(_account);
if (locked == 0) mayHaveLockedTokens[_account] = false;
return balances[_account].sub(locked);
}
internal LockSlots.pNumberOfLockedTokens keyboard_arrow_up
Source Code
function pNumberOfLockedTokens(address _account)
private
view
returns (uint256 locked)
{
uint256[LOCK_SLOTS] storage term = lockTerm[_account];
uint256[LOCK_SLOTS] storage amnt = lockAmnt[_account];
for (uint256 i; i < LOCK_SLOTS; i++) {
if (term[i] >= now) locked = locked.add(amnt[i]);
}
}