ERC20
This contract is an ERC20 token.
Name
StormX
Symbol
STMX
Decimals
18
Total Supply
10,000,000,000 STMX
About link description
StormX (STMX) is a cryptocurrency and operates on the Ethereum platform. StormX has a current supply of 10,000,000,000. The last known price of StormX is 0.01608895 USD and is down -4.72 over the last 24 hours. It is currently trading on 22 active market(s) with $10,440,822.25 traded over the last 24 hours. More information can be found at https://stormx.io/.
Stats
Public Functions
33
Event Types
12
Code Size
67,029 bytes
Library Use
Uses SafeMath for uint256.
Events (12) keyboard_arrow_up
State Variables (17) keyboard_arrow_up
Functions
name keyboard_arrow_up
symbol keyboard_arrow_up
decimals keyboard_arrow_up
totalSupply keyboard_arrow_up
balanceOf keyboard_arrow_up
transfer keyboard_arrow_up
Requirements help
Source Code
function transfer(address recipient, uint256 amount) public returns (bool) {
require(
unlockedBalanceOf(_msgSender()) >= amount,
"Not enough unlocked token balance"
);
return super.transfer(recipient, amount);
}
allowance keyboard_arrow_up
approve keyboard_arrow_up
Requirements help
Source Code
function approve(address spender, uint256 amount) public returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
transferFrom keyboard_arrow_up
Requirements help
Source Code
function transferFrom(
address sender,
address recipient,
uint256 amount
) public returns (bool) {
require(
unlockedBalanceOf(sender) >= amount,
"Not enough unlocked token balance of sender"
);
// if the msg.sender is charging ``sender`` for a GSN fee
// allowance does not apply
// so that no user approval is required for GSN calls
if (_msgSender() == address(this) || _msgSender() == swap) {
_transfer(sender, recipient, amount);
return true;
} else {
return super.transferFrom(sender, recipient, amount);
}
}
increaseAllowance keyboard_arrow_up
Requirements help
Source Code
function increaseAllowance(address spender, uint256 addedValue)
public
returns (bool)
{
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender].add(addedValue)
);
return true;
}
decreaseAllowance keyboard_arrow_up
Requirements help
Source Code
function decreaseAllowance(address spender, uint256 subtractedValue)
public
returns (bool)
{
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender].sub(
subtractedValue,
"ERC20: decreased allowance below zero"
)
);
return true;
}
owner keyboard_arrow_up
isOwner keyboard_arrow_up
renounceOwnership keyboard_arrow_up
transferOwnership keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Source Code
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
getHubAddr keyboard_arrow_up
relayHubVersion keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function relayHubVersion() public view returns (string memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return "1.0.0";
}
preRelayedCall keyboard_arrow_up
Requirements help
Source Code
function preRelayedCall(bytes calldata context) external returns (bytes32) {
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
return _preRelayedCall(context);
}
postRelayedCall keyboard_arrow_up
Parameters help
Requirements help
Source Code
function postRelayedCall(
bytes calldata context,
bool success,
uint256 actualCharge,
bytes32 preRetVal
) external {
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
_postRelayedCall(context, success, actualCharge, preRetVal);
}
acceptRelayedCall keyboard_arrow_up
Parameters help
Source Code
function acceptRelayedCall(
address relay,
address from,
bytes calldata encodedFunction,
uint256 transactionFee,
uint256 gasPrice,
uint256 gasLimit,
uint256 nonce,
bytes calldata approvalData,
uint256 maxPossibleCharge
) external view returns (uint256, bytes memory) {
(bool accept, bool chargeBefore) = _acceptRelayedCall(from, encodedFunction);
if (accept) {
return _approveRelayedCall(abi.encode(from, chargeBefore));
} else {
return _rejectRelayedCall(INSUFFICIENT_BALANCE);
}
}
setStormXReserve keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function setStormXReserve(address newReserve) public onlyOwner returns (bool) {
require(newReserve != address(0), "Invalid reserve address");
stormXReserve = newReserve;
emit StormXReserveSet(newReserve);
return true;
}
setChargeFee keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Source Code
function setChargeFee(uint256 newFee) public onlyOwner returns (bool) {
chargeFee = newFee;
emit ChargeFeeSet(newFee);
return true;
}
unlockedBalanceOf keyboard_arrow_up
lock keyboard_arrow_up
Requirements help
Source Code
function lock(uint256 amount) public returns (bool) {
address account = _msgSender();
require(unlockedBalanceOf(account) >= amount, "Not enough unlocked tokens");
lockedBalanceOf[account] = lockedBalanceOf[account].add(amount);
emit TokenLocked(account, amount);
return true;
}
unlock keyboard_arrow_up
Requirements help
Source Code
function unlock(uint256 amount) public returns (bool) {
address account = _msgSender();
require(lockedBalanceOf[account] >= amount, "Not enough locked tokens");
lockedBalanceOf[account] = lockedBalanceOf[account].sub(amount);
emit TokenUnlocked(account, amount);
return true;
}
transfers keyboard_arrow_up
Modifiers help
transfersAllowed checks for the following:
transfersEnabled must be true
Requirements help
Source Code
function transfers(address[] memory recipients, uint256[] memory values)
public
transfersAllowed
returns (bool)
{
require(recipients.length == values.length, "Input lengths do not match");
for (uint256 i = 0; i < recipients.length; i++) {
transfer(recipients[i], values[i]);
}
return true;
}
enableTransfers keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Source Code
function enableTransfers(bool enable) public onlyOwner returns (bool) {
transfersEnabled = enable;
emit TransfersEnabled(enable);
return true;
}
mint keyboard_arrow_up
Requirements help
initialized must be true
Source Code
function mint(address account, uint256 amount) public {
require(initialized, "The contract is not initialized yet");
require(_msgSender() == swap, "not authorized to mint");
_mint(account, amount);
}
initialize keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function initialize(address _swap) public onlyOwner {
require(!initialized, "cannot initialize twice");
require(_swap != address(0), "invalid swap address");
swap = _swap;
transfersEnabled = true;
emit TransfersEnabled(true);
initialized = true;
emit SwapAddressAdded(_swap);
}
assignRewardRole keyboard_arrow_up
reward keyboard_arrow_up
Modifiers help
onlyAuthorized checks for the following:
One or more of the following:
-
rewardRole
must be equal to
the result of calling _msgSender
- OR
the result of calling _msgSender
must be equal to
the result of calling owner
Source Code
function reward(address recipient, uint256 amount) public onlyAuthorized {
require(recipient != address(0), "Invalid recipient address provided");
require(transfer(recipient, amount), "Transfer fails when rewarding a user");
// If `autoStakingDisabled[user] == false`,
// auto staking is enabled for current user
if (!autoStakingDisabled[recipient]) {
lockedBalanceOf[recipient] = lockedBalanceOf[recipient].add(amount);
emit TokenLocked(recipient, amount);
}
}
rewards keyboard_arrow_up
Modifiers help
onlyAuthorized checks for the following:
One or more of the following:
-
rewardRole
must be equal to
the result of calling _msgSender
- OR
the result of calling _msgSender
must be equal to
the result of calling owner
Requirements help
Source Code
function rewards(address[] memory recipients, uint256[] memory values)
public
onlyAuthorized
{
require(recipients.length == values.length, "Input lengths do not match");
for (uint256 i = 0; i < recipients.length; i++) {
reward(recipients[i], values[i]);
}
}
setAutoStaking keyboard_arrow_up
Source Code
function setAutoStaking(bool enabled) public {
// If `enabled == false`, set `autoStakingDisabled[user] = true`
autoStakingDisabled[_msgSender()] = !enabled;
emit AutoStakingSet(_msgSender(), enabled);
}
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 StormXToken._acceptRelayedCall keyboard_arrow_up
Source Code
function _acceptRelayedCall(address from, bytes memory encodedFunction)
internal
view
returns (bool accept, bool chargeBefore)
{
bool chargeBefore = true;
uint256 unlockedBalance = unlockedBalanceOf(from);
if (unlockedBalance < chargeFee) {
// charge users after executing the encoded function
chargeBefore = false;
bytes4 selector = readBytes4(encodedFunction, 0);
if (selector == bytes4(keccak256("unlock(uint256)"))) {
// unlocked token balance for the user if transaction succeeds
uint256 amount = uint256(getParam(encodedFunction, 0)).add(
unlockedBalance
);
return (amount >= chargeFee, chargeBefore);
} else if (
selector == bytes4(keccak256("transferFrom(address,address,uint256)"))
) {
address sender = address(getParam(encodedFunction, 0));
address recipient = address(getParam(encodedFunction, 1));
uint256 amount = getParam(encodedFunction, 2);
bool accept = recipient == from &&
// no real effect of `transferfrom()` if `sender == recipient`
sender != recipient &&
// `from` can have enough unlocked token balance after the transaction
amount.add(unlockedBalance) >= chargeFee &&
// check `transferFrom()` can be executed successfully
unlockedBalanceOf(sender) >= amount &&
allowance(sender, from) >= amount;
return (accept, chargeBefore);
} else {
// if rejects the call, the value of chargeBefore does not matter
return (false, chargeBefore);
}
} else {
return (true, chargeBefore);
}
}
internal StormXGSNRecipient._acceptRelayedCall keyboard_arrow_up
internal StormXGSNRecipient._preRelayedCall keyboard_arrow_up
Source Code
function _preRelayedCall(bytes memory context) internal returns (bytes32) {
(address user, bool chargeBefore) = abi.decode(context, (address, bool));
// charge the user with specified amount of fee
// if the user is not calling ``convert()``
if (chargeBefore) {
require(
token.transferFrom(user, stormXReserve, chargeFee),
"Charging fails before executing the function"
);
}
return "";
}
internal StormXGSNRecipient._postRelayedCall keyboard_arrow_up
Parameters help
Source Code
function _postRelayedCall(
bytes memory context,
bool success,
uint256 actualCharge,
bytes32 preRetVal
) internal {
(address user, bool chargeBefore) = abi.decode(context, (address, bool));
if (!chargeBefore) {
require(
token.transferFrom(user, stormXReserve, chargeFee),
"Charging fails after executing the function"
);
}
}
internal StormXGSNRecipient.readBytes4 keyboard_arrow_up
Requirements help
Source Code
function readBytes4(bytes memory b, uint256 index)
internal
pure
returns (bytes4 result)
{
require(b.length >= index + 4, "GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED");
// Arrays are prefixed by a 32 byte length field
index += 32;
// Read the bytes4 from array memory
assembly {
result := mload(add(b, index))
// Solidity does not require us to clean the trailing bytes.
// We do it anyway
result := and(
result,
0xFFFFFFFF00000000000000000000000000000000000000000000000000000000
)
}
return result;
}
internal StormXGSNRecipient.readBytes32 keyboard_arrow_up
Requirements help
Source Code
function readBytes32(bytes memory b, uint256 index)
internal
pure
returns (bytes32 result)
{
require(b.length >= index + 32, "GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED");
// Arrays are prefixed by a 256 bit length parameter
index += 32;
// Read the bytes32 from array memory
assembly {
result := mload(add(b, index))
}
return result;
}
internal StormXGSNRecipient.readUint256 keyboard_arrow_up
internal StormXGSNRecipient.getParam keyboard_arrow_up
internal GSNRecipient._upgradeRelayHub keyboard_arrow_up
Requirements help
Source Code
function _upgradeRelayHub(address newRelayHub) internal {
address currentRelayHub = _relayHub;
require(
newRelayHub != address(0),
"GSNRecipient: new RelayHub is the zero address"
);
require(
newRelayHub != currentRelayHub,
"GSNRecipient: new RelayHub is the current one"
);
emit RelayHubChanged(currentRelayHub, newRelayHub);
_relayHub = newRelayHub;
}
internal GSNRecipient._withdrawDeposits keyboard_arrow_up
internal GSNRecipient._msgSender keyboard_arrow_up
internal GSNRecipient._msgData keyboard_arrow_up
internal GSNRecipient._preRelayedCall keyboard_arrow_up
internal GSNRecipient._postRelayedCall keyboard_arrow_up
Parameters help
Source Code
function _postRelayedCall(
bytes memory context,
bool success,
uint256 actualCharge,
bytes32 preRetVal
) internal;
internal GSNRecipient._approveRelayedCall keyboard_arrow_up
internal GSNRecipient._approveRelayedCall keyboard_arrow_up
internal GSNRecipient._rejectRelayedCall keyboard_arrow_up
internal GSNRecipient._computeCharge keyboard_arrow_up
Source Code
function _computeCharge(
uint256 gas,
uint256 gasPrice,
uint256 serviceFee
) internal pure returns (uint256) {
// The fee is expressed as a percentage. E.g. a value of 40 stands for a 40% fee, so the recipient will be
// charged for 1.4 times the spent amount.
return (gas * gasPrice * (100 + serviceFee)) / 100;
}
internal GSNRecipient._getRelayedCallSender keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _getRelayedCallSender() private pure returns (address payable result) {
// We need to read 20 bytes (an address) located at array index msg.data.length - 20. In memory, the array
// is prefixed with a 32-byte length value, so we first add 32 to get the memory read index. However, doing
// so would leave the address in the upper 20 bytes of the 32-byte word, which is inconvenient and would
// require bit shifting. We therefore subtract 12 from the read index so the address lands on the lower 20
// bytes. This can always be done due to the 32-byte prefix.
// The final memory read index is msg.data.length - 20 + 32 - 12 = msg.data.length. Using inline assembly is the
// easiest/most-efficient way to perform this operation.
// These fields are not accessible from assembly
bytes memory array = msg.data;
uint256 index = msg.data.length;
// solhint-disable-next-line no-inline-assembly
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
result := and(
mload(add(array, index)),
0xffffffffffffffffffffffffffffffffffffffff
)
}
return result;
}
internal GSNRecipient._getRelayedCallData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _getRelayedCallData() private pure returns (bytes memory) {
// RelayHub appends the sender address at the end of the calldata, so in order to retrieve the actual msg.data,
// we must strip the last 20 bytes (length of an address type) from it.
uint256 actualDataLength = msg.data.length - 20;
bytes memory actualData = new bytes(actualDataLength);
for (uint256 i = 0; i < actualDataLength; ++i) {
actualData[i] = msg.data[i];
}
return actualData;
}
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
internal Ownable.constructor keyboard_arrow_up
internal Ownable._transferOwnership keyboard_arrow_up
Source Code
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
internal ERC20._transfer keyboard_arrow_up
Requirements help
Source Code
function _transfer(
address sender,
address recipient,
uint256 amount
) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(
amount,
"ERC20: transfer amount exceeds balance"
);
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
internal ERC20._mint keyboard_arrow_up
Source Code
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
internal ERC20._burn keyboard_arrow_up
Source Code
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
_balances[account] = _balances[account].sub(
amount,
"ERC20: burn amount exceeds balance"
);
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
internal ERC20._approve keyboard_arrow_up
Requirements help
Source Code
function _approve(
address owner,
address spender,
uint256 amount
) internal {
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);
}
internal ERC20._burnFrom keyboard_arrow_up
Requirements help
Source Code
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(
account,
_msgSender(),
_allowances[account][_msgSender()].sub(
amount,
"ERC20: burn amount exceeds allowance"
)
);
}
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}