2018-10-24 12:52:11 +00:00
|
|
|
|
pragma solidity >=0.0;
|
2017-07-05 10:28:15 +00:00
|
|
|
|
|
|
|
|
|
import "./announcementTypes.sol";
|
|
|
|
|
import "./safeMath.sol";
|
|
|
|
|
import "./module.sol";
|
|
|
|
|
import "./moduleHandler.sol";
|
|
|
|
|
import "./tokenDB.sol";
|
|
|
|
|
|
|
|
|
|
contract thirdPartyContractAbstract {
|
2018-08-07 20:12:52 +00:00
|
|
|
|
function receiveCorionToken(address, uint256, bytes calldata) external returns (bool, uint256) {}
|
|
|
|
|
function approvedCorionToken(address, uint256, bytes calldata) external returns (bool) {}
|
2017-07-05 10:28:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-20 16:25:23 +00:00
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @title Corion Platform Token
|
|
|
|
|
* @author iFA @ Corion Platform
|
|
|
|
|
*
|
|
|
|
|
*/
|
2017-07-05 10:28:15 +00:00
|
|
|
|
contract token is safeMath, module, announcementTypes {
|
|
|
|
|
/*
|
|
|
|
|
module callbacks
|
|
|
|
|
*/
|
2019-09-16 12:33:43 +00:00
|
|
|
|
function replaceModule(address payable addr) external override returns (bool success) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( super.isModuleHandler(msg.sender) );
|
|
|
|
|
require( db.replaceOwner(addr) );
|
|
|
|
|
super._replaceModule(addr);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
modifier isReady {
|
2018-06-21 11:58:38 +00:00
|
|
|
|
(bool _success, bool _active) = super.isActive();
|
2018-08-01 19:57:12 +00:00
|
|
|
|
require( _success && _active );
|
2017-07-05 10:28:15 +00:00
|
|
|
|
_;
|
|
|
|
|
}
|
2020-05-20 16:25:23 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
string public name = "Corion";
|
|
|
|
|
string public symbol = "COR";
|
|
|
|
|
uint8 public decimals = 6;
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
tokenDB public db;
|
2018-09-12 14:21:43 +00:00
|
|
|
|
address payable public icoAddr;
|
2017-07-05 10:28:15 +00:00
|
|
|
|
uint256 public transactionFeeRate = 20;
|
|
|
|
|
uint256 public transactionFeeRateM = 1e3;
|
|
|
|
|
uint256 public transactionFeeMin = 20000;
|
|
|
|
|
uint256 public transactionFeeMax = 5000000;
|
|
|
|
|
uint256 public transactionFeeBurn = 80;
|
2018-09-12 14:21:43 +00:00
|
|
|
|
address payable public exchangeAddress;
|
2017-07-05 10:28:15 +00:00
|
|
|
|
bool public isICO = true;
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
mapping(address => bool) public genesis;
|
2018-07-04 17:20:51 +00:00
|
|
|
|
|
2020-06-23 12:14:24 +00:00
|
|
|
|
constructor(bool forReplace, address payable moduleHandler, address dbAddr, address payable icoContractAddr, address payable exchangeContractAddress, address payable[] memory genesisAddr, uint256[] memory genesisValue) payable {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Installation function
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
When _icoAddr is defined, 0.2 ether has to be attached as many times as many genesis addresses are given
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@forReplace This address will be replaced with the old one or not.
|
|
|
|
|
@moduleHandler Modulhandler's address
|
|
|
|
|
@dbAddr Address of database
|
|
|
|
|
@icoContractAddr Address of ICO contract
|
|
|
|
|
@exchangeContractAddress Address of Market in order to buy gas during ICO
|
|
|
|
|
@genesisAddr Array of Genesis addresses
|
|
|
|
|
@genesisValue Array of balance of genesis addresses
|
|
|
|
|
*/
|
|
|
|
|
super.registerModuleHandler(moduleHandler);
|
2018-06-12 09:05:49 +00:00
|
|
|
|
require( dbAddr != address(0x00) );
|
|
|
|
|
require( icoContractAddr != address(0x00) );
|
|
|
|
|
require( exchangeContractAddress != address(0x00) );
|
2017-07-05 10:28:15 +00:00
|
|
|
|
db = tokenDB(dbAddr);
|
|
|
|
|
icoAddr = icoContractAddr;
|
|
|
|
|
exchangeAddress = exchangeContractAddress;
|
|
|
|
|
isICO = ! forReplace;
|
|
|
|
|
if ( ! forReplace ) {
|
2018-07-12 18:07:16 +00:00
|
|
|
|
require( db.replaceOwner(address(this)) );
|
2017-07-05 10:28:15 +00:00
|
|
|
|
assert( genesisAddr.length == genesisValue.length );
|
2018-07-05 12:32:32 +00:00
|
|
|
|
require( address(this).balance >= genesisAddr.length * 0.2 ether );
|
2017-07-05 10:28:15 +00:00
|
|
|
|
for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) {
|
|
|
|
|
genesis[genesisAddr[a]] = true;
|
|
|
|
|
require( db.increase(genesisAddr[a], genesisValue[a]) );
|
|
|
|
|
if ( ! genesisAddr[a].send(0.2 ether) ) {}
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Mint(genesisAddr[a], genesisValue[a]);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function closeIco() external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
ICO finished. It can be called only by ICO contract
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
require( msg.sender == icoAddr );
|
|
|
|
|
isICO = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice `msg.sender` approves `spender` to spend `amount` tokens on its behalf.
|
|
|
|
|
* @param spender The address of the account able to transfer the tokens
|
|
|
|
|
* @param amount The amount of tokens to be approved for transfer
|
|
|
|
|
* @param nonce The transaction count of the authorised address
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success True if the approval was successful
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
|
|
|
|
function approve(address spender, uint256 amount, uint256 nonce) isReady external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Authorise another address to use a certain quantity of the authorising owner’s balance
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@spender Address of authorised party
|
|
|
|
|
@amount Token quantity
|
|
|
|
|
@nonce Transaction count
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
_approve(spender, amount, nonce);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice `msg.sender` approves `spender` to spend `amount` tokens on its behalf and notify the spender from your approve with your `extraData` data.
|
|
|
|
|
* @param spender The address of the account able to transfer the tokens
|
|
|
|
|
* @param amount The amount of tokens to be approved for transfer
|
|
|
|
|
* @param nonce The transaction count of the authorised address
|
|
|
|
|
* @param extraData Data to give forward to the receiver
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success True if the approval was successful
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
2018-08-07 20:12:52 +00:00
|
|
|
|
function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes calldata extraData) isReady external returns (bool success) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Authorise another address to use a certain quantity of the authorising owner’s balance
|
|
|
|
|
Following the transaction the receiver address `approvedCorionToken` function is called by the given data
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@spender Authorized address
|
|
|
|
|
@amount Token quantity
|
|
|
|
|
@extraData Extra data to be received by the receiver
|
|
|
|
|
@nonce Transaction count
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
_approve(spender, amount, nonce);
|
|
|
|
|
require( thirdPartyContractAbstract(spender).approvedCorionToken(msg.sender, amount, extraData) );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function _approve(address spender, uint256 amount, uint256 nonce) internal {
|
|
|
|
|
/*
|
|
|
|
|
Internal Function to authorise another address to use a certain quantity of the authorising owner’s balance.
|
|
|
|
|
If the transaction count not match the authorise fails.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@spender Address of authorised party
|
|
|
|
|
@amount Token quantity
|
|
|
|
|
@nonce Transaction count
|
|
|
|
|
*/
|
|
|
|
|
require( msg.sender != spender );
|
|
|
|
|
require( db.balanceOf(msg.sender) >= amount );
|
|
|
|
|
require( db.setAllowance(msg.sender, spender, amount, nonce) );
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Approval(msg.sender, spender, amount);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
}
|
2018-07-04 17:20:51 +00:00
|
|
|
|
|
|
|
|
|
function allowance(address owner, address spender) public view returns (uint256 remaining, uint256 nonce) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Get the quantity of tokens given to be used
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner Authorising address
|
|
|
|
|
@spender Authorised address
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@remaining Tokens to be spent
|
|
|
|
|
@nonce Transaction count
|
|
|
|
|
*/
|
2018-06-21 11:58:38 +00:00
|
|
|
|
(bool _success, uint256 _remaining, uint256 _nonce) = db.getAllowance(owner, spender);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( _success );
|
|
|
|
|
return (_remaining, _nonce);
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice Send `amount` Corion tokens to `to` from `msg.sender`
|
|
|
|
|
* @param to The address of the recipient
|
|
|
|
|
* @param amount The amount of tokens to be transferred
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success Whether the transfer was successful or not
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
|
|
|
|
function transfer(address to, uint256 amount) isReady external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Start transaction, token is sent from caller’s address to receiver’s address
|
|
|
|
|
Transaction fee is to be deducted.
|
|
|
|
|
If receiver is not a natural address but a person, he will be called
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@to To who
|
|
|
|
|
@amount Quantity
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
bytes memory _data;
|
|
|
|
|
if ( isContract(to) ) {
|
|
|
|
|
_transferToContract(msg.sender, to, amount, _data);
|
|
|
|
|
} else {
|
|
|
|
|
_transfer( msg.sender, to, amount, true);
|
|
|
|
|
}
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Transfer(msg.sender, to, amount, _data);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice Send `amount` tokens to `to` from `from` on the condition it is approved by `from`
|
|
|
|
|
* @param from The address holding the tokens being transferred
|
|
|
|
|
* @param to The address of the recipient
|
|
|
|
|
* @param amount The amount of tokens to be transferred
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success True if the transfer was successful
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
|
|
|
|
function transferFrom(address from, address to, uint256 amount) isReady external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Start transaction to send a quantity from a given address to another address. (approve / allowance). This can be called only by the address approved in advance
|
|
|
|
|
Transaction fee is to be deducted
|
|
|
|
|
If receiver is not a natural address but a person, he will be called
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@from From who.
|
|
|
|
|
@to To who
|
|
|
|
|
@amount Quantity
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
if ( from != msg.sender ) {
|
2018-06-21 11:58:38 +00:00
|
|
|
|
(bool _success, uint256 _reamining, uint256 _nonce) = db.getAllowance(from, msg.sender);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( _success );
|
|
|
|
|
_reamining = safeSub(_reamining, amount);
|
|
|
|
|
_nonce = safeAdd(_nonce, 1);
|
|
|
|
|
require( db.setAllowance(from, msg.sender, _reamining, _nonce) );
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit AllowanceUsed(msg.sender, from, amount);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
}
|
|
|
|
|
bytes memory _data;
|
|
|
|
|
if ( isContract(to) ) {
|
|
|
|
|
_transferToContract(from, to, amount, _data);
|
|
|
|
|
} else {
|
|
|
|
|
_transfer( from, to, amount, true);
|
|
|
|
|
}
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Transfer(from, to, amount, _data);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice Send `amount` tokens to `to` from `from` on the condition it is approved by `from`
|
|
|
|
|
* @param from The address holding the tokens being transferred
|
|
|
|
|
* @param to The address of the recipient
|
|
|
|
|
* @param amount The amount of tokens to be transferred
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success True if the transfer was successful
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
|
|
|
|
function transferFromByModule(address from, address to, uint256 amount, bool fee) isReady external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Start transaction to send a quantity from a given address to another address
|
|
|
|
|
Only ModuleHandler can call it
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@from From who
|
|
|
|
|
@to To who.
|
|
|
|
|
@amount Quantity
|
|
|
|
|
@fee Deduct transaction fee - yes or no?
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
bytes memory _data;
|
|
|
|
|
require( super.isModuleHandler(msg.sender) );
|
|
|
|
|
_transfer( from, to, amount, fee);
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Transfer(from, to, amount, _data);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice Send `amount` Corion tokens to `to` from `msg.sender` and notify the receiver from your transaction with your `extraData` data
|
|
|
|
|
* @param to The contract address of the recipient
|
|
|
|
|
* @param amount The amount of tokens to be transferred
|
|
|
|
|
* @param extraData Data to give forward to the receiver
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success Whether the transfer was successful or not
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
2018-08-07 20:12:52 +00:00
|
|
|
|
function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Start transaction to send a quantity from a given address to another address
|
|
|
|
|
After transaction the function `receiveCorionToken`of the receiver is called by the given data
|
|
|
|
|
When sending an amount, it is possible the total amount cannot be processed, the remaining amount is sent back with no fee charged
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@to To who.
|
|
|
|
|
@amount Quantity
|
|
|
|
|
@extraData Extra data the receiver will get
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
if ( isContract(to) ) {
|
|
|
|
|
_transferToContract(msg.sender, to, amount, extraData);
|
|
|
|
|
} else {
|
|
|
|
|
_transfer( msg.sender, to, amount, true);
|
|
|
|
|
}
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Transfer(msg.sender, to, amount, extraData);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2018-07-14 21:42:01 +00:00
|
|
|
|
function _transferToContract(address from, address to, uint256 amount, bytes memory extraData) internal {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Internal function to start transactions to a contract
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@from From who
|
|
|
|
|
@to To who.
|
|
|
|
|
@amount Quantity
|
|
|
|
|
@extraData Extra data the receiver will get
|
|
|
|
|
*/
|
|
|
|
|
_transfer(from, to, amount, exchangeAddress == to);
|
2018-06-21 11:58:38 +00:00
|
|
|
|
(bool _success, uint256 _back) = thirdPartyContractAbstract(to).receiveCorionToken(from, amount, extraData);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( _success );
|
|
|
|
|
require( amount > _back );
|
|
|
|
|
if ( _back > 0 ) {
|
|
|
|
|
_transfer(to, from, _back, false);
|
|
|
|
|
}
|
|
|
|
|
_processTransactionFee(from, amount - _back);
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function _transfer(address from, address to, uint256 amount, bool fee) internal {
|
|
|
|
|
/*
|
|
|
|
|
Internal function to start transactions. When Tokens are sent, transaction fee is charged
|
|
|
|
|
During ICO transactions are allowed only from genesis addresses.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
After sending the tokens, the ModuleHandler is notified and it will broadcast the fact among members
|
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
The 0xa636a97578d26a3b76b060bbc18226d954cf3757 address are blacklisted.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@from From who
|
|
|
|
|
@to To who
|
|
|
|
|
@amount Quantity
|
|
|
|
|
@fee Deduct transaction fee - yes or no?
|
|
|
|
|
*/
|
|
|
|
|
if( fee ) {
|
2018-06-21 11:58:38 +00:00
|
|
|
|
(bool success, uint256 _fee) = getTransactionFee(amount);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( success );
|
|
|
|
|
require( db.balanceOf(from) >= amount + _fee );
|
|
|
|
|
}
|
2018-06-12 09:05:49 +00:00
|
|
|
|
require( from != address(0x00) && to != address(0x00) && to != 0xa636A97578d26A3b76B060Bbc18226d954cf3757 );
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( ( ! isICO) || genesis[from] );
|
|
|
|
|
require( db.decrease(from, amount) );
|
|
|
|
|
require( db.increase(to, amount) );
|
|
|
|
|
if ( fee ) { _processTransactionFee(from, amount); }
|
|
|
|
|
if ( isICO ) {
|
|
|
|
|
require( ico(icoAddr).setInterestDB(from, db.balanceOf(from)) );
|
|
|
|
|
require( ico(icoAddr).setInterestDB(to, db.balanceOf(to)) );
|
|
|
|
|
}
|
|
|
|
|
require( moduleHandler(moduleHandlerAddress).broadcastTransfer(from, to, amount) );
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @notice Transaction fee will be deduced from `owner` for transacting `value`
|
|
|
|
|
* @param owner The address where will the transaction fee deduced
|
|
|
|
|
* @param value The base for calculating the fee
|
2019-10-21 22:05:34 +00:00
|
|
|
|
* @return success True if the transfer was successful
|
2017-07-05 10:28:15 +00:00
|
|
|
|
*/
|
|
|
|
|
function processTransactionFee(address owner, uint256 value) isReady external returns (bool success) {
|
|
|
|
|
/*
|
2018-08-01 19:57:12 +00:00
|
|
|
|
Charge transaction fee. It can be called only by moduleHandler
|
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner From who.
|
|
|
|
|
@value Quantity to calculate the fee
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
require( super.isModuleHandler(msg.sender) );
|
|
|
|
|
_processTransactionFee(owner, value);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function _processTransactionFee(address owner, uint256 value) internal {
|
|
|
|
|
/*
|
|
|
|
|
Internal function to charge the transaction fee. A certain quantity is burnt, the rest is sent to the Schelling game prize pool.
|
|
|
|
|
No transaction fee during ICO.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner From who
|
|
|
|
|
@value Quantity to calculate the fee
|
|
|
|
|
*/
|
|
|
|
|
if ( isICO ) { return; }
|
2018-06-21 11:58:38 +00:00
|
|
|
|
(bool _success, uint256 _fee) = getTransactionFee(value);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( _success );
|
|
|
|
|
uint256 _forBurn = _fee * transactionFeeBurn / 100;
|
|
|
|
|
uint256 _forSchelling = _fee - _forBurn;
|
|
|
|
|
bool _found;
|
|
|
|
|
address _schellingAddr;
|
|
|
|
|
(_success, _found, _schellingAddr) = moduleHandler(moduleHandlerAddress).getModuleAddressByName('Schelling');
|
|
|
|
|
require( _success );
|
2018-06-12 09:05:49 +00:00
|
|
|
|
if ( _schellingAddr != address(0x00) && _found) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( db.decrease(owner, _forSchelling) );
|
|
|
|
|
require( db.increase(_schellingAddr, _forSchelling) );
|
|
|
|
|
_burn(owner, _forBurn);
|
|
|
|
|
bytes memory _data;
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Transfer(owner, _schellingAddr, _forSchelling, _data);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
require( moduleHandler(moduleHandlerAddress).broadcastTransfer(owner, _schellingAddr, _forSchelling) );
|
|
|
|
|
} else {
|
|
|
|
|
_burn(owner, _fee);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2018-07-02 09:14:28 +00:00
|
|
|
|
function getTransactionFee(uint256 value) public view returns (bool success, uint256 fee) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Transaction fee query.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@value Quantity to calculate the fee
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
@fee Amount of Transaction fee
|
|
|
|
|
*/
|
|
|
|
|
if ( isICO ) { return (true, 0); }
|
|
|
|
|
fee = value * transactionFeeRate / transactionFeeRateM / 100;
|
|
|
|
|
if ( fee > transactionFeeMax ) { fee = transactionFeeMax; }
|
|
|
|
|
else if ( fee < transactionFeeMin ) { fee = transactionFeeMin; }
|
|
|
|
|
return (true, fee);
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function mint(address owner, uint256 value) isReady external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Generating tokens. It can be called only by ICO contract or the moduleHandler.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner Address
|
|
|
|
|
@value Amount.
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
require( super.isModuleHandler(msg.sender) || msg.sender == icoAddr );
|
|
|
|
|
_mint(owner, value);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function _mint(address owner, uint256 value) internal {
|
|
|
|
|
/*
|
|
|
|
|
Internal function to generate tokens
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner Token is credited to this address
|
|
|
|
|
@value Quantity
|
|
|
|
|
*/
|
|
|
|
|
require( db.increase(owner, value) );
|
2018-06-12 09:05:49 +00:00
|
|
|
|
require( moduleHandler(moduleHandlerAddress).broadcastTransfer(address(0x00), owner, value) );
|
2017-07-05 10:28:15 +00:00
|
|
|
|
if ( isICO ) {
|
|
|
|
|
require( ico(icoAddr).setInterestDB(owner, db.balanceOf(owner)) );
|
|
|
|
|
}
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Mint(owner, value);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function burn(address owner, uint256 value) isReady external returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Burning the token. Can call only modulehandler
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner Burn the token from this address
|
|
|
|
|
@value Quantity
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
require( super.isModuleHandler(msg.sender) );
|
|
|
|
|
_burn(owner, value);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function _burn(address owner, uint256 value) internal {
|
|
|
|
|
/*
|
|
|
|
|
Internal function to burn the token
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner Burn the token from this address
|
|
|
|
|
@value Quantity
|
|
|
|
|
*/
|
|
|
|
|
require( db.decrease(owner, value) );
|
2018-06-12 09:05:49 +00:00
|
|
|
|
require( moduleHandler(moduleHandlerAddress).broadcastTransfer(owner, address(0x00), value) );
|
2018-06-27 08:35:38 +00:00
|
|
|
|
emit Burn(owner, value);
|
2017-07-05 10:28:15 +00:00
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function isContract(address addr) internal returns (bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Internal function to check if the given address is natural, or a contract
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@addr Address to be checked
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Is the address crontact or not
|
|
|
|
|
*/
|
|
|
|
|
uint256 _codeLength;
|
|
|
|
|
assembly {
|
|
|
|
|
_codeLength := extcodesize(addr)
|
|
|
|
|
}
|
|
|
|
|
return _codeLength > 0;
|
|
|
|
|
}
|
2018-07-04 17:20:51 +00:00
|
|
|
|
|
|
|
|
|
function balanceOf(address owner) public view returns (uint256 value) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Token balance query
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@owner Address
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@value Balance of address
|
|
|
|
|
*/
|
|
|
|
|
return db.balanceOf(owner);
|
|
|
|
|
}
|
2018-07-04 17:20:51 +00:00
|
|
|
|
|
|
|
|
|
function totalSupply() public view returns (uint256 value) {
|
2017-07-05 10:28:15 +00:00
|
|
|
|
/*
|
|
|
|
|
Total token quantity query
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@value Total token quantity
|
|
|
|
|
*/
|
|
|
|
|
return db.totalSupply();
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
function configure(announcementType aType, uint256 value) isReady external returns(bool success) {
|
|
|
|
|
/*
|
|
|
|
|
Token settings configuration.It can be call only by moduleHandler
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@aType Type of setting
|
|
|
|
|
@value Value
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
@success Was the Function successful?
|
|
|
|
|
*/
|
|
|
|
|
require( super.isModuleHandler(msg.sender) );
|
|
|
|
|
if ( aType == announcementType.transactionFeeRate ) { transactionFeeRate = value; }
|
|
|
|
|
else if ( aType == announcementType.transactionFeeMin ) { transactionFeeMin = value; }
|
|
|
|
|
else if ( aType == announcementType.transactionFeeMax ) { transactionFeeMax = value; }
|
|
|
|
|
else if ( aType == announcementType.transactionFeeBurn ) { transactionFeeBurn = value; }
|
|
|
|
|
else { return false; }
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-08-01 19:57:12 +00:00
|
|
|
|
|
2017-07-05 10:28:15 +00:00
|
|
|
|
event AllowanceUsed(address indexed spender, address indexed owner, uint256 indexed value);
|
|
|
|
|
event Mint(address indexed addr, uint256 indexed value);
|
|
|
|
|
event Burn(address indexed addr, uint256 indexed value);
|
|
|
|
|
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
|
|
|
|
event Transfer(address indexed _from, address indexed _to, uint256 indexed _value, bytes _extraData);
|
|
|
|
|
}
|