pragma solidity >=0.0; import "./safeMath.sol"; import "./tokenDB.sol"; import "./module.sol"; contract thirdPartyPContractAbstract { function receiveCorionPremiumToken(address, uint256, bytes calldata) external returns (bool, uint256) {} function approvedCorionPremiumToken(address, uint256, bytes calldata) external returns (bool) {} } contract ptokenDB is tokenDB {} /** * * @title Corion Platform Premium Token * @author iFA @ Corion Platform * */ contract premium is module, safeMath { function replaceModule(address payable addr) external override returns (bool success) { require( super.isModuleHandler(payable(msg.sender)) ); require( db.replaceOwner(addr) ); super._replaceModule(addr); return true; } modifier isReady { (bool _success, bool _active) = super.isActive(); require( _success && _active ); _; } string public name = "Corion Premium"; string public symbol = "CORP"; uint8 public decimals = 0; address public icoAddr; tokenDB public db; bool public isICO; mapping(address => bool) public genesis; constructor(bool forReplace, address payable moduleHandler, address dbAddress, address icoContractAddr, address[] memory genesisAddr, uint256[] memory genesisValue) { /* Setup function. If an ICOaddress is defined then the balance of the genesis addresses will be set as well. @forReplace This address will be replaced with the old one or not. @moduleHandler Modulhandler’s address @dbAddress Address of database @icoContractAddr Address of ico contract. @genesisAddr Array of the genesis addresses. @genesisValue Array of the balance of the genesis addresses */ super.registerModuleHandler(moduleHandler); require( dbAddress != address(0x00) ); db = ptokenDB(dbAddress); if ( ! forReplace ) { require( db.replaceOwner(address(this)) ); isICO = true; icoAddr = icoContractAddr; assert( genesisAddr.length == genesisValue.length ); for ( uint256 a=0 ; a= amount ); require( db.setAllowance(msg.sender, spender, amount, nonce) ); emit Approval(msg.sender, spender, amount); } function allowance(address owner, address spender) public view returns (uint256 remaining, uint256 nonce) { /* Get the quantity of tokens given to be used @owner Authorising address @spender Authorised address @remaining Tokens to be spent @nonce Transaction count */ (bool _success, uint256 _remaining, uint256 _nonce) = db.getAllowance(owner, spender); require( _success ); return (_remaining, _nonce); } /** * @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 * @return success Whether the transfer was successful or not */ function transfer(address to, uint256 amount) isReady external returns (bool success) { /* Launch a transaction where the token is sent from the sender’s address to the receiver’s address. Transaction fee is going to be added as well. If the receiver is not a natural address but also a person then she/he will be invited as well. @to For who @amount Amount @success Was the function successful? */ bytes memory _data; if ( isContract(to) ) { transferToContract(msg.sender, to, amount, _data); } else { _transfer(msg.sender, to, amount); } emit Transfer(msg.sender, to, amount, _data); return true; } /** * @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 * @return success True if the transfer was successful */ function transferFrom(address from, address to, uint256 amount) isReady external returns (bool success) { /* Launch a transaction where we transfer from a given address to another one. It can only be called by an address which was allowed before. Transaction fee will be charged too. If the receiver is not a natural address but also a person then she/he will be invited as well @from From who? @to For who? @amount Amount @success If the function was successful. */ if ( from != msg.sender ) { (bool _success, uint256 _reamining, uint256 _nonce) = db.getAllowance(from, msg.sender); require( _success ); _reamining = safeSub(_reamining, amount); _nonce = safeAdd(_nonce, 1); require( db.setAllowance(from, msg.sender, _reamining, _nonce) ); emit AllowanceUsed(msg.sender, from, amount); } bytes memory _data; if ( isContract(to) ) { transferToContract(from, to, amount, _data); } else { _transfer( from, to, amount); } emit Transfer(from, to, amount, _data); return true; } /** * @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 * @return success Whether the transfer was successful or not */ function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) { /* Launch a transaction where we transfer from a given address to another one. After thetransaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data. @to For who? @amount Amount @extraData Extra data that will be given to the receiver @success If the function was successful. */ if ( isContract(to) ) { transferToContract(msg.sender, to, amount, extraData); } else { _transfer( msg.sender, to, amount); } emit Transfer(msg.sender, to, amount, extraData); return true; } function transferToContract(address from, address to, uint256 amount, bytes memory extraData) internal { /* Inner function in order to transact a contract. @to For who? @amount Amount @extraData Extra data that will be given to the receiver */ _transfer(from, to, amount); (bool _success, uint256 _back) = thirdPartyPContractAbstract(to).receiveCorionPremiumToken(from, amount, extraData); require( _success ); require( amount > _back ); if ( _back > 0 ) { _transfer(to, from, _back); } } function _transfer(address from, address to, uint256 amount) isReady internal { /* Inner function to launch a transaction. During the ICO transactions are only possible from the genesis address. 0xa636a97578d26a3b76b060bbc18226d954cf3757 address is blacklisted. @from From how? @to For who? @amount Amount */ require( from != address(0x00) && to != address(0x00) && to != 0xa636A97578d26A3b76B060Bbc18226d954cf3757 ); require( ( ! isICO) || genesis[from] ); require( db.decrease(from, amount) ); require( db.increase(to, amount) ); } function mint(address owner, uint256 value) external returns (bool success) { /* Generating tokens. It can be called only by ICO contract. @owner Address @value Amount. @success Was the Function successful? */ require( msg.sender == icoAddr || isICO ); _mint(owner, value); return true; } function _mint(address owner, uint256 value) isReady internal { /* Inner function to create a token. @owner Address of crediting the token. @value Amount */ require( db.increase(owner, value) ); emit Mint(owner, value); } function isContract(address addr) internal returns (bool success) { /* Inner function in order to check if the given address is a natural address or a contract. @addr The address which is needed to be checked. @success Is the address crontact or not */ uint256 _codeLength; assembly { _codeLength := extcodesize(addr) } return _codeLength > 0; } function balanceOf(address owner) public view returns (uint256 value) { /* Token balance query @owner Address @value Balance of address */ return db.balanceOf(owner); } function totalSupply() public view returns (uint256 value) { /* Total token quantity query @value Total token quantity */ return db.totalSupply(); } 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 _value, bytes _extraData); }