Contract Details
What exactly does QMatic do?
Beware of Scammers, QPoker's team never ask your wallet private key or extra information about you.
$QMatic is using AccessControl strategy to create roles, it's public data and you can check which wallet address has the accessibility to the $QMatic.
$QMatic Smart Contract
Polygon Mainnet : ( Coming soon).
Github Repository: QPokerLTD/QMatic.
Audit Paper: (Coming soon).
Audit Company: (Coming soon).
Solidity Versions: ^0.8.9, ^0.8.0, ^0.8.1 .
Solidity Compiler Version: 0.8.17 .
Optimizer runs: 200.
List of Smart Contracts and interfaces use for $QMatic:
ERC20Burnable.sol (See on OpenZeppelin).
AccessControl.sol
Math.sol (See on OpenZeppelin).
Pausable.sol (See on OpenZeppelin).
SafeMath.sol
Strings.sol (See on OpenZeppelin).
QPokerToken.sol
This contract inherited from ERC20
,
ERC20Burnable
,
Pausable
, AccessControl
.
Stored Variables:
bytes32 public constant TOKEN_MECHANISM_MANAGER
this variable is related to the AccessControl contract and it contains the valuation of keccak256("TOKEN_MECHANISM_MANAGER");
Mechanism Manager is the access of QPoker economy team to change the state of mechanism that used in the $QMatic contract, we describe it fully on ERC20.sol file.
bytes32 public constant ECONOMIC_MANAGER
this variable is related to the AccessControl contract and it contains the valuation of keccak256("ECONOMIC_MANAGER");
also in the economy team there is a Key member who decides at the final for minting the token.
bytes32 public constant QPOKER_ORACLE
this variable is related to the AccessControl contract and it contains the valuation of keccak256("QPOKER_ORACLE")
QPoker Oracle is the access of QPoker Automated Service named Oracle, this service has the access to manage the $QMatic ecosystem.
Functions:
function pause() public onlyRole(TOKEN_MECHANISM_MANAGER)
Token Mechanism manager can pause the contract in order to change the state of current used mechanism in the contract.
pause will lock all the token transfers (get more information on ERC20.sol)
more information about pause system is available on Pausable.sol (See on OpenZeppelin)
function unpause() public onlyRole(TOKEN_MECHANISM_MANAGER)
Token Mechanism manager can pause the contract in order to change the state of current used mechanism in the contract.
unpause will unlock the previous locking state of contract.
more information about pause system is available on Pausable.sol (See on OpenZeppelin)
function mint(address to, uint256 amount) public onlyRole(ECONOMIC_MANAGER)
QPoker project will mint the tokens step by step, we won't release all the $QMatic tokens at the begining and every minting transaction will be detailed in QPoker Oracle service.
also every minting events will announced in QPoker Telegram Channel.
function _beforeTokenTransfer( address from, address to, uint256 amount) internal override whenNotPaused
As OpenZeppelin said:
" Hook that is called before any transfer of tokens. This includes minting and burning.
Calling conditions:
when
from
andto
are both non-zero,amount
offrom
's tokens will be transferred toto
.when
from
is zero,amount
tokens will be minted forto
.when
to
is zero,amount
offrom
's tokens will be burned.from
andto
are never both zero.
To learn more about hooks, head to Using Hooks. "
and we used this function to just putting the rule of whenNotPaused
and this function is required that not paused state.
function _beforeChangeMechanism() internal override onlyRole(TOKEN_MECHANISM_MANAGER)
At this time this hook is used just to verify that the sender must be TOKEN_MECHANISM_MANAGER
.
function _beforeWalletRelatedAction() internal override onlyRole(QPOKER_ORACLE)
At this time this hook is used just to verify that the sender must be QPOKER_ORACLE
.
ERC20.sol
This file contains all the abilities of $QMatic token and it inherited from Context,
IERC20
,
IERC20Metadata
.
Structures:
Structures:
WalletInformationAndStatus
struct WalletInformationAndStatus {
uint256 id;
bool is_lock;
uint256 locked_balance;
}
uint256 id
: every wallet has an assignedid
, it's a part of our business logic in oracle service.bool is_lock
: If this attribute has the valuation equal totrue
, the mapped wallet address cannot transfer any of his $QMatic.uint256 locked_balance
: this attribute will clarify the amounts of locked token in a wallet, based on QPoker whitepaper everyone who bought token in got token in Pre-sale Round phase or Seed Round phase have a vesting schedule,also the people who got winning prize in airdrop events will have a vesting schedule and at the end of each campaign the schedule will be announced.
locked_balance
value will change by the Oracle service during the time and everyone can notice it from their panel.
ActiveMechanism
struct ActiveBurningMechanism {
bool is_active;
address treasury_middleman;
uint256 treasury_share_in_part_of_decimal;
uint256 burn_share_in_part_of_decimal;
uint256 total_mechanism_share_in_part_of_decimal;
uint256 share_cap_in_token;
uint256 total_share_decimal;
uint256 each_share_decimal;
}
bool is_active
: describes that is QPoker project activated the mechanism or notaddress treasury_middleman
: describes the address of the treasury, it can be a automated wallet or Smart Contract. and the treasury strategy will be announced in QPoker Official Telegram Channel.uint256 treasury_share_in_part_of_decimal
: based on total share that will be calculated bytotal_mechanism_share_in_part_of_decimal
orshare_cap_in_token
, Smart Contract will calculate amount of $QMatic that should transfer to the treasury on every transaction.uint256 burn_share_in_part_of_decimal
: based on total share that will be calculated bytotal_mechanism_share_in_part_of_decimal
orshare_cap_in_token
, Smart Contract will calculate amount of $QMatic that should burn on every transaction.uint256 total_mechanism_share_in_part_of_decimal
: describes the amount of token that mechanism affects on that.uint256 share_cap_in_token
: if calculated part of the transfer amount went greater than theshare_cap_in_token
the amount of affected by mechanism will change to theshare_cap_in_token
.uint256 total_share_decimal
: in solidity we don't have decimals so if project decides to affect on 0.1% of the transactionstotal_share_decimal
will be equaled to 1000 and the affected amount will calculated by this formula =>affected_amount = (transfer_amount * total_mechanism_share_in_part_of_decimal)/total_share_decimal
uint256 each_share_decimal
: in solidity we don't have decimals so if project decides to burn on 0.01% of the affected share,total_share_decimal
will be equaled to 1000 and the burn amount will calculated by this formula =>burn_amount = (affected_amount * burn_share_in_part_of_decimal)/each_share_decimal
and the rest of 99.99% of treasury share will transfer to treasury
Stored Variables:
Stored Variables:
_totalSupply
uint256 private _totalSupply;
Describes total minted token by the smart contract and the FUNCTIONNAME
will returns the amount of _totalSupply
more information is available at here.
_cap
uint256 private immutable _cap;
to avoiding of minting token more than we describe in the QPoker Whitepaper we created this variable and it will be checked on every minting event and the amount of minting + the amount of total supply must be equal or lower than the _cap
_name
string private _name;
Stores the name of the token for this project it's "QPoker Token
"
more information is available at here.
_symbol
string private _symbol;
Stores the symbol of the token => for this project it's "QMatic
"
more information is available at here.
_mechanism
ActiveMechanism private _mechanism;
it will stores the mechanism of the smart contract.
more information is available at here.
_wallet_id_counter
uint256 private _wallet_id_counter = 1;
Safe counter to assign the id to each new wallet.
more information is available at here.
_whiteListZeroMechanism
mapping(address => bool) private _whiteListZeroMechanism;
every transfers of $QMatic will happened between two wallets and in this scenario we called it from
wallet and to
wallet, if one of them exists in the _whiteListZeroMechanism
, the mechanism will not affect on that transaction.
for example: the game platform contract address is one of the items in the _whiteListZeroMechanism
, and the transactions to/from the gameplatform doesen't have any affects of mechanism. also for some of the exchanges that we announce the list of them in QPoker Oracle.
_wallets
mapping(address => WalletInformationAndStatus) private _wallets;
contains list of wallet addresses with the information that we described in here.
_balances
mapping(address => uint256) private _balances;
Stores the balance value of each wallet address
more information is available at here.
_allowances
mapping(address => mapping(address => uint256)) private _allowances;ol
Stores 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.
Functions:
Functions:
function cap() public view returns (uint256)
returns the stored value in _cap
variable.
function incrementWalletId() internal
increments the stored value in _wallet_id_counter
by 1.
function approveNewWallet(address account) internal
this function will add the account
value from argument to the _wallets
, increments wallet id and announced it with WalletId
event.
function lockWalletByAdmin(address account) public
this function will executed by the QPOKER_ORACLE
and locks the target wallet address that got from the argument (account
).
this function placed here in order to ban scammers, from the community reports.
function unlockWalletByAdmin(address account) public
this function will executed by the QPOKER_ORACLE
and unlocks the target wallet address that got from the argument (account
).
function _isWalletLocked(address account) internal view returns (bool)
will check locking state of the wallet address that got from the argument
and returns true/false
based on the logic.
function getMoreDataFromWallet(address account) public view returns (WalletInformationAndStatus memory)
will returns the WalletInformationAndStatus
of the specific wallet address that got from the argument.
function _beforeWalletRelatedAction() internal virtual
executes logic befor any logic in lockWalletByAdmin, unlockWalletByAdmin, addWalletWhiteList, removeWalletFromWhiteList, batchWalletBalanceLock and transferWithVestingSchedule
function addWalletWhiteList(address target) public
adds the target
address to the _whiteListZeroMechanism
.
function removeWalletFromWhiteList(address target) public
removes the target from the _whiteListZeroMechanism
.
function _walletBalanceLock( uint256 qpoker_oracle_id, address account, uint256 amount ) internal
it's will lock amounts of the balance that Oracle mentioned by the arguments.
more information is here.
function batchWalletBalanceLock( uint256[] memory qpoker_oracle_id, address[] memory account, uint256[] memory amount) public
same as _walletBalanceLock
but it will get array of wallets.
NOTE: the first rule of execution the logic in this function is : qpoker_oracle_id.length == account.length == amount.length
function _canTransferToken(address from, uint256 amount) internal view
this Hook will check that _balances[from] - _wallets[from].locked_balance >= amount
function _beforeChangeMechanism() internal virtual
this Hook will execute the logic at the start of updateActiveMecanism, disableActiveMecanism
.
function updateActiveMecanism( address treasury_middleman_, uint256 treasury_share_in_percentage_, uint256 burn_share_in_percentage_, uint256 total_mechanism_share_in_percentage_, uint256 share_cap_in_token_ ) public
will update the ActiveMechanism
state by the arguments and announce the changed version by MechanismState
event.
function disableActiveMecanism() public
will disables the ActiveMechanism
state by the arguments and announce the changed version by MechanismState
event.
function getActiveMecanismStatus() public view returns (ActiveMechanism memory)
will returns current ActiveMecanism
state.
function activeMechanismProcess( address from, uint256 amount, uint256 accountBalance ) internal returns (uint256)
this function will be called by _transfer
method and calculates the burn and trasury mechanisms, at the end returns the remaining amount for transfer to the _transfer
method.
function name() public view virtual override returns (string memory)
returns the stored value in _name
variable.
function symbol() public view virtual override returns (string memory)
returns the stored value in _symbol
variable.
function decimals() public view virtual override returns (uint8)
returns the decimal of token (it will return 18)
function totalSupply() public view virtual override returns (uint256)
returns the stored value in _totalSupply
variable.
function balanceOf(address account) public view virtual override returns (uint256)
returns the current balance of the account
.
function transfer(address to, uint256 amount) public virtual override returns (bool)
will transfers specific amount of the $QMatic from the caller to target wallet address.
NOTE: this function will send the tokens by _transfer
method.
function transferWithVestingSchedule( address to, uint256 amount, uint256 block_amount, uint256 oracel_id ) public returns (bool)
this function will used by oracle for transferring the specific amount of token to the target with vesting schedule mechanism.
function allowance(address owner, address spender) public view virtual override returns (uint256)
Returns the amount which _spender
is still allowed to withdraw from _owner
.
more information here.
function approve(address spender, uint256 amount) public virtual override returns (bool)
Allows _spender
to withdraw from your account multiple times, up to the _value
amount. If this function is called again it overwrites the current allowance with _value
.
more information here.
function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool)
Transfers _value
amount of tokens from address _from
to address _to
, and MUST fire the Transfer
event.
The transferFrom
method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD throw
unless the _from
account has deliberately authorized the sender of the message via some mechanism.
more information here.
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool)
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.
more information here.
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool)
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 leastsubtractedValue
.
more information here.
function _transfer( address from, address to, uint256 amount ) internal
almost same with the EIP-20
standard but the diffrence is :
this function will executes the _canTransferToken
,
approveNewWallet
and calculates the amount to transfer by the activeMechanismProcess
method.
function _burn(address account, uint256 amount) internal virtual
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 leastamount
tokens.
function _approve( address owner, address spender, uint256 amount ) internal virtual
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 _spendAllowance( address owner, address spender, uint256 amount ) internal virtual
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 _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual
Hook that is called before any transfer of tokens. This includes minting and burning.
function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual
Hook that is called after any transfer of tokens. This includes minting and burning.
Events:
Events:
event Transfer(address indexed from, address indexed to, uint256 value);
Emitted when value
tokens are moved from one account (from
) to another (to
).
Note that value
may be zero.
event Approval( address indexed owner, address indexed spender, uint256 value );
Emitted when the allowance of a spender
for an owner
is set by a call to approve
. value
is the new allowance.
event MechanismState( uint256 event_date, bool is_active, address treasury_middleman, uint256 treasury_share_in_percentage, uint256 burn_share_in_percentage, uint256 total_mechanism_share_in_percentage, uint256 share_cap_in_token);
Emitted when the ActiveMecanism
changed.
event WalletTokenLockVesting( uint256 indexed oracle_id, address user, uint256 blocked_amount, uint256 event_date);
Emitted when the transferWithVestingSchedule
or batchWalletBalanceLock
executes.
event WalletId(uint256 indexed id, address indexed user);
Emitted when new wallet account pushes to the _wallets
list.
AccessControl.sol
manages the AccessControls of specific addresses.
Stored Variables:
Stored Variables:
bytes32 public constant SUPER_ADMIN_ROLE = keccak256("SUPER_ADMIN");
key of the SUPER_ADMIN_ROLE
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
key of the default admin.
NOTE: SUPER_ADMIN_ROLE
can change DEFAULT_ADMIN_ROLE
but DEFAULT_ADMIN_ROLE
cannot change SUPER_ADMIN_ROLE
.
bool private is_inited = false;
it will be used for initializing the AccessControl , after the initializing finished the stored value of is_inited
will change to true
.
Modifiers:
Modifiers:
modifier onlyRole(bytes32 role)
checks that only user can access to the rest of the logic who mapped in the _roles
.
modifier onlyForInit()
only allows to execute the rest of the logics if is_inited
was equal to false
.
Functions:
Functions:
function initRole() public onlyForInit
will sets the admin and superadmin then changes the is_inited
to true
.
this function depends on the decision of onlyForInit
.
function hasRole(bytes32 role, address account) public view returns (bool)
checks the role and the wallet address if the target wallet address has the role this function will return true
otherwise it will return false
.
function getAdmin() public view returns (address)
will returnes the address of DEFAULT_ADMIN_ROLE
.
function getSuperAdmin() public view returns (address)
will returns the address of SUPER_ADMIN_ROLE
.
Last updated