Last active
August 11, 2019 17:59
-
-
Save rezarahimian/673e8b6e35aaa684510b175ab56658da to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.2+commit.1df8f40c.js&optimize=true&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.0; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.10; | |
// ------------------------------------------------------------------------------- | |
// ERC20: ERC Token Standard #20 Interface | |
// Https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md | |
// A draft specification that defines what a token smart contract should look like | |
// ------------------------------------------------------------------------------- | |
contract ERC20Interface { | |
function totalSupply() external view returns (uint256); | |
function balanceOf(address _account) external view returns (uint256); | |
function transfer(address _to, uint256 _tokens) external returns (bool); | |
function approve(address _spender, uint256 _tokens) external returns (bool); | |
function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool); | |
function allowance(address _account, address _spender) external view returns (uint256); | |
event Transfer(address indexed _from, address indexed _to, uint256 _tokens); | |
event Approval(address indexed _tokenOwner, address indexed _spender, uint256 _tokens); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ----------------------------------------------------------------------------------------- | |
// Compilation of: | |
// 1- https://theethereum.wiki/w/index.php/ERC20_Token_Standard | |
// 2- https://www.ethereum.org/token | |
// 3- https://github.com/OpenZeppelin/openzeppelin-solidity/blob/9b3710465583284b8c4c5d2245749246bb2e0094/contracts/token/ERC20/ERC20.sol | |
// 4- https://github.com/ConsenSys/Tokens/blob/fdf687c69d998266a95f15216b1955a4965a0a6d/contracts/eip20/EIP20.sol | |
// 5- https://gist.github.com/flygoing/2956f0d3b5e662a44b83b8e4bec6cca6 | |
// ----------------------------------------------------------------------------------------- | |
// In order to work with tokens, we will need to install a chrome extention called MetaMask. | |
// It is a Ethereum wallet that runs within chrome browser and allows us to interact with | |
// Ethereum DApp by injecting a Javascript library called Web3 into the browser. | |
// By doing that any Ethereum connected web application will use that library to talk to | |
// Ethereum network. | |
// ----------------------------------------------------------------------------------------- | |
pragma solidity ^0.5.9; | |
contract ERC20Interface { | |
function totalSupply() external view returns (uint256); | |
function balanceOf(address _account) external view returns (uint256); | |
function transfer(address _to, uint256 _tokens) external returns (bool); | |
function approve(address _spender, uint256 _tokens) external returns (bool); | |
function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool); | |
function allowance(address _account, address _spender) external view returns (uint256); | |
event Transfer(address indexed _from, address indexed _to, uint256 _tokens); | |
event Approval(address indexed _tokenOwner, address indexed _spender, uint256 _tokens); | |
} | |
// | |
// @title SafeMath | |
// @dev Math operations with safety checks that revert on error | |
// | |
library SafeMath { | |
// Multiplies two numbers, throws on overflow. | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
if (a == 0) { return 0; } | |
uint256 c = a * b; | |
require(c / a == b); | |
return c; | |
} | |
// Integer division of two numbers, truncating the quotient. | |
function div(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
require(b > 0); // Solidity automatically throws when dividing by 0 | |
uint256 c = a / b; | |
return c; | |
} | |
// Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
require(b <= a); | |
uint256 c = a - b; | |
return c; | |
} | |
// Adds two numbers, throws on overflow. | |
function add(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
uint256 c = a + b; | |
require(c >= a); | |
return c; | |
} | |
function percent(uint256 numerator, uint256 denominator, uint256 precision) internal pure returns(uint256) | |
{ | |
uint256 _numerator = numerator * 10 ** (precision + 1); | |
return ((_numerator / denominator) + 5) / 10; | |
} | |
} | |
// ----------------------------------------------------------------------------------------- | |
contract TokenV1 is ERC20Interface{ | |
using SafeMath for uint256; | |
string public constant name = "Token v1"; | |
string public constant symbol = "TKNv1"; | |
uint8 public constant decimals = 18; // 1 token can be broken down up to 18 decimal places (like ETH) | |
mapping(address => mapping (address => uint256)) allowed; // Owner of account approves the transfer of an amount to another account | |
mapping(address => uint256) balances; // Balances for each account | |
address private owner = address(0); | |
uint256 private _initialSupply = 1000000; | |
uint256 private _totalSupply; | |
constructor() public { | |
owner = msg.sender; | |
_totalSupply = _initialSupply * 10 ** uint256(decimals);// Update total supply with the decimal amount | |
balances[owner] = _totalSupply; | |
emit Transfer(address(0), owner, _totalSupply); | |
} | |
// ----------------------------------------------------------------------------- | |
// Returns total amount of token in circulation | |
// ----------------------------------------------------------------------------- | |
function totalSupply() public view returns (uint256) { | |
return _totalSupply; | |
} | |
// ----------------------------------------------------------------------------- | |
// Get the token balance for an address | |
// ----------------------------------------------------------------------------- | |
function balanceOf(address _tokenOwner) public view returns (uint256 tokens) { | |
return balances[_tokenOwner]; | |
} | |
// ----------------------------------------------------------------------------- | |
// Transfer the balance (value) from owner's account to another account | |
// ----------------------------------------------------------------------------- | |
function transfer(address _to, uint256 _tokens) public returns (bool success) { | |
require(_tokens > 0); // Check for more than zero token | |
require(balances[msg.sender] >= _tokens); // Check if the sender has enough | |
require(balances[_to] + _tokens >= balances[_to]); // Check for overflows | |
balances[msg.sender] = balances[msg.sender].sub(_tokens); // Subtract from the sender | |
balances[_to] = balances[_to].add(_tokens); // Add the same to the recipient | |
emit Transfer(msg.sender, _to, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// Special type of Transfer and make it possible to give permission to another address | |
// to spend token on your behalf. | |
// It sends _tokens amount of tokens from address _from to address _to | |
// The transferFrom method is used for a withdraw workflow, allowing contracts to send | |
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge | |
// fees in sub-currencies; the command should fail unless the _from account has | |
// deliberately authorized the sender of the message via some mechanism | |
// ----------------------------------------------------------------------------- | |
function transferFrom(address _from, address _to, uint256 _tokens) public returns (bool success) { | |
require(_to != address(0)); | |
require(balances[_from] >= _tokens); // Check if approver has enough tokens | |
require(allowed[_from][msg.sender] >= _tokens); // Check allowance | |
balances[_from] = balances[_from].sub(_tokens); | |
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_tokens); | |
balances[_to] = balances[_to].add(_tokens); | |
emit Transfer(_from, _to, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// It helps to give permission to another address to spend tokens on your behalf. | |
// Allow _spender to withdraw from your account, multiple times, up to the _tokens amount. | |
// If this function is called again it overwrites the current allowance with _tokens. | |
// ----------------------------------------------------------------------------- | |
function approve(address _spender, uint256 _tokens) public returns (bool success) { | |
require(_spender != address(0)); | |
allowed[msg.sender][_spender] = _tokens; | |
emit Approval(msg.sender, _spender, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// Returns the amount of tokens approved by the owner that can be | |
// transferred to the spender's account. In other word, how many tokens we gave | |
// permission to another address to spend | |
// ----------------------------------------------------------------------------- | |
function allowance(address _tokenOwner, address _spender) public view returns (uint256 remaining) { | |
return allowed[_tokenOwner][_spender]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ----------------------------------------------------------------------------------------- | |
// Compilation of: | |
// 1- https://theethereum.wiki/w/index.php/ERC20_Token_Standard | |
// 2- https://www.ethereum.org/token | |
// 3- https://github.com/OpenZeppelin/openzeppelin-solidity/blob/9b3710465583284b8c4c5d2245749246bb2e0094/contracts/token/ERC20/ERC20.sol | |
// 4- https://github.com/ConsenSys/Tokens/blob/fdf687c69d998266a95f15216b1955a4965a0a6d/contracts/eip20/EIP20.sol | |
// 5- https://gist.github.com/flygoing/2956f0d3b5e662a44b83b8e4bec6cca6 | |
// ----------------------------------------------------------------------------------------- | |
// In order to work with tokens, we will need to install a chrome extention called MetaMask. | |
// It is a Ethereum wallet that runs within chrome browser and allows us to interact with | |
// Ethereum DApp by injecting a Javascript library called Web3 into the browser. | |
// By doing that any Ethereum connected web application will use that library to talk to | |
// Ethereum network. | |
// ----------------------------------------------------------------------------------------- | |
pragma solidity ^0.5.9; | |
contract ERC20Interface { | |
function totalSupply() external view returns (uint256); | |
function balanceOf(address _account) external view returns (uint256); | |
function transfer(address _to, uint256 _tokens) external returns (bool); | |
function approve(address _spender, uint256 _tokens) external returns (bool); | |
function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool); | |
function allowance(address _account, address _spender) external view returns (uint256); | |
event Transfer(address indexed _from, address indexed _to, uint256 _tokens); | |
event Approval(address indexed _tokenOwner, address indexed _spender, uint256 _tokens); | |
} | |
// | |
// @title SafeMath | |
// @dev Math operations with safety checks that revert on error | |
// | |
library SafeMath { | |
// Multiplies two numbers, throws on overflow. | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
if (a == 0) { return 0; } | |
uint256 c = a * b; | |
require(c / a == b); | |
return c; | |
} | |
// Integer division of two numbers, truncating the quotient. | |
function div(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
require(b > 0); // Solidity automatically throws when dividing by 0 | |
uint256 c = a / b; | |
return c; | |
} | |
// Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
require(b <= a); | |
uint256 c = a - b; | |
return c; | |
} | |
// Adds two numbers, throws on overflow. | |
function add(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
uint256 c = a + b; | |
require(c >= a); | |
return c; | |
} | |
function percent(uint256 numerator, uint256 denominator, uint256 precision) internal pure returns(uint256) | |
{ | |
uint256 _numerator = numerator * 10 ** (precision + 1); | |
return ((_numerator / denominator) + 5) / 10; | |
} | |
} | |
// ----------------------------------------------------------------------------------------- | |
contract TokenV2 is ERC20Interface{ | |
using SafeMath for uint256; | |
string public constant name = "Token V2"; | |
string public constant symbol = "TKNv2"; | |
uint8 public constant decimals = 18; // 1 token can be broken down up to 18 decimal places (like ETH) | |
mapping(address => mapping (address => uint256)) private allowed; // Owner of account approves the transfer of an amount to another account | |
mapping(address => mapping (address => uint256)) private transferred; // Transfered tokens from approved account | |
mapping(address => uint256) balances; // Balances for each account | |
address private owner = address(0); | |
uint256 private _initialSupply = 1000000; | |
uint256 private _totalSupply; | |
constructor() public { | |
owner = msg.sender; | |
_totalSupply = _initialSupply * 10 ** uint256(decimals);// Update total supply with the decimal amount | |
balances[owner] = _totalSupply; | |
emit Transfer(address(0), owner, _totalSupply); | |
} | |
// ----------------------------------------------------------------------------- | |
// Returns total amount of token in circulation | |
// ----------------------------------------------------------------------------- | |
function totalSupply() public view returns (uint256) { | |
return _totalSupply; | |
} | |
// ----------------------------------------------------------------------------- | |
// Get the token balance for an address | |
// ----------------------------------------------------------------------------- | |
function balanceOf(address _tokenOwner) public view returns (uint256 tokens) { | |
return balances[_tokenOwner]; | |
} | |
// ----------------------------------------------------------------------------- | |
// Transfer the balance (value) from owner's account to another account | |
// ----------------------------------------------------------------------------- | |
function transfer(address _to, uint256 _tokens) public returns (bool success) { | |
require(_tokens > 0); // Check for more than zero token | |
require(balances[msg.sender] >= _tokens); // Check if the sender has enough | |
require(balances[_to] + _tokens >= balances[_to]); // Check for overflows | |
balances[msg.sender] = balances[msg.sender].sub(_tokens); // Subtract from the sender | |
balances[_to] = balances[_to].add(_tokens); // Add the same to the recipient | |
emit Transfer(msg.sender, _to, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// Special type of Transfer and make it possible to give permission to another address | |
// to spend token on your behalf. | |
// It sends _tokens amount of tokens from address _from to address _to | |
// The transferFrom method is used for a withdraw workflow, allowing contracts to send | |
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge | |
// fees in sub-currencies; the command should fail unless the _from account has | |
// deliberately authorized the sender of the message via some mechanism | |
// ----------------------------------------------------------------------------- | |
function transferFrom(address _from, address _to, uint256 _tokens) public returns (bool success) { | |
require(_to != address(0)); | |
require(balances[_from] >= _tokens); // Check if approver has enough tokens | |
require(allowed[_from][msg.sender] >= _tokens); // Check allowance | |
balances[_from] = balances[_from].sub(_tokens); | |
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_tokens); | |
transferred[_from][msg.sender] = transferred[_from][msg.sender].add(_tokens); | |
balances[_to] = balances[_to].add(_tokens); | |
emit Transfer(_from, _to, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// It helps to give permission to another address to spend tokens on your behalf. | |
// Allow _spender to withdraw from your account, multiple times, up to the _tokens amount. | |
// If this function is called again it overwrites the current allowance with _tokens. | |
// ----------------------------------------------------------------------------- | |
function approve(address _spender, uint256 _tokens) public returns (bool success) { | |
require(_spender != address(0)); | |
uint256 allowedTokens = 0; | |
uint256 initiallyAllowed = allowed[msg.sender][_spender].add(transferred[msg.sender][_spender]); | |
//Aprover reduces allowance | |
if (_tokens <= initiallyAllowed){ | |
if (transferred[msg.sender][_spender] < _tokens){ // If less tokens had been transferred. | |
allowedTokens = _tokens.sub(transferred[msg.sender][_spender]); // Allows _spender for the rest | |
} | |
} | |
//Approver increases allowance | |
else{ | |
allowedTokens = _tokens.sub(initiallyAllowed); | |
allowedTokens = allowed[msg.sender][_spender].add(allowedTokens); | |
} | |
allowed[msg.sender][_spender] = allowedTokens; | |
emit Approval(msg.sender, _spender, allowedTokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// Returns the amount of tokens approved by the owner that can be | |
// transferred to the spender's account. In other word, how many tokens we gave | |
// permission to another address to spend | |
// ----------------------------------------------------------------------------- | |
function allowance(address _tokenOwner, address _spender) public view returns (uint256 remaining) { | |
return allowed[_tokenOwner][_spender]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ----------------------------------------------------------------------------------------- | |
// Compilation of: | |
// 1- https://theethereum.wiki/w/index.php/ERC20_Token_Standard | |
// 2- https://www.ethereum.org/token | |
// 3- https://github.com/OpenZeppelin/openzeppelin-solidity/blob/9b3710465583284b8c4c5d2245749246bb2e0094/contracts/token/ERC20/ERC20.sol | |
// 4- https://github.com/ConsenSys/Tokens/blob/fdf687c69d998266a95f15216b1955a4965a0a6d/contracts/eip20/EIP20.sol | |
// 5- https://gist.github.com/flygoing/2956f0d3b5e662a44b83b8e4bec6cca6 | |
// ----------------------------------------------------------------------------------------- | |
// In order to work with tokens, we will need to install a chrome extention called MetaMask. | |
// It is a Ethereum wallet that runs within chrome browser and allows us to interact with | |
// Ethereum DApp by injecting a Javascript library called Web3 into the browser. | |
// By doing that any Ethereum connected web application will use that library to talk to | |
// Ethereum network. | |
// ----------------------------------------------------------------------------------------- | |
pragma solidity ^0.5.9; | |
contract ERC20Interface { | |
function totalSupply() external view returns (uint256); | |
function balanceOf(address _account) external view returns (uint256); | |
function transfer(address _to, uint256 _tokens) external returns (bool); | |
function approve(address _spender, uint256 _tokens) external returns (bool); | |
function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool); | |
function allowance(address _account, address _spender) external view returns (uint256); | |
event Transfer(address indexed _from, address indexed _to, uint256 _tokens); | |
event Approval(address indexed _tokenOwner, address indexed _spender, uint256 _tokens); | |
} | |
// | |
// @title SafeMath | |
// @dev Math operations with safety checks that revert on error | |
// | |
library SafeMath { | |
// Multiplies two numbers, throws on overflow. | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
if (a == 0) { return 0; } | |
uint256 c = a * b; | |
require(c / a == b); | |
return c; | |
} | |
// Integer division of two numbers, truncating the quotient. | |
function div(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
require(b > 0); // Solidity automatically throws when dividing by 0 | |
uint256 c = a / b; | |
return c; | |
} | |
// Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
require(b <= a); | |
uint256 c = a - b; | |
return c; | |
} | |
// Adds two numbers, throws on overflow. | |
function add(uint256 a, uint256 b) internal pure returns (uint256) | |
{ | |
uint256 c = a + b; | |
require(c >= a); | |
return c; | |
} | |
function percent(uint256 numerator, uint256 denominator, uint256 precision) internal pure returns(uint256) | |
{ | |
uint256 _numerator = numerator * 10 ** (precision + 1); | |
return ((_numerator / denominator) + 5) / 10; | |
} | |
} | |
// ----------------------------------------------------------------------------------------- | |
contract TokenV3 is ERC20Interface{ | |
using SafeMath for uint256; | |
string public constant name = "Token V3"; | |
string public constant symbol = "TKNv3"; | |
uint8 public constant decimals = 18; // 1 token can be broken down up to 18 decimal places (like ETH) | |
mapping(address => mapping (address => uint256)) private allowed; // Owner of account approves the transfer of an amount to another account | |
mapping(address => mapping (address => uint256)) private transferred; // Transfered tokens from approved account | |
mapping(address => uint256) balances; // Balances for each account | |
address private owner = address(0); | |
uint256 private _initialSupply = 1000000; | |
uint256 private _totalSupply; | |
constructor() public { | |
owner = msg.sender; | |
_totalSupply = _initialSupply * 10 ** uint256(decimals);// Update total supply with the decimal amount | |
balances[owner] = _totalSupply; | |
emit Transfer(address(0), owner, _totalSupply); | |
} | |
// ----------------------------------------------------------------------------- | |
// Returns total amount of token in circulation | |
// ----------------------------------------------------------------------------- | |
function totalSupply() public view returns (uint256 tokens) { | |
return _totalSupply; | |
} | |
// ----------------------------------------------------------------------------- | |
// Get the token balance for an address | |
// ----------------------------------------------------------------------------- | |
function balanceOf(address _tokenOwner) public view returns (uint256 tokens) { | |
return balances[_tokenOwner]; | |
} | |
// ----------------------------------------------------------------------------- | |
// Transfer the balance (value) from owner's account to another account | |
// ----------------------------------------------------------------------------- | |
function transfer(address _to, uint256 _tokens) public returns (bool success) { | |
require(_tokens > 0); // Check for more than zero token | |
require(balances[msg.sender] >= _tokens); // Check if the sender has enough | |
require(balances[_to] + _tokens >= balances[_to]); // Check for overflows | |
balances[msg.sender] = balances[msg.sender].sub(_tokens); // Subtract from the sender | |
balances[_to] = balances[_to].add(_tokens); // Add the same to the recipient | |
emit Transfer(msg.sender, _to, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// Special type of Transfer and make it possible to give permission to another address | |
// to spend token on your behalf. | |
// It sends _tokens amount of tokens from address _from to address _to | |
// The transferFrom method is used for a withdraw workflow, allowing contracts to send | |
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge | |
// fees in sub-currencies; the command should fail unless the _from account has | |
// deliberately authorized the sender of the message via some mechanism | |
// ----------------------------------------------------------------------------- | |
function transferFrom(address _from, address _to, uint256 _tokens) public returns (bool success) { | |
require(_to != address(0)); | |
require(balances[_from] >= _tokens); // Checks if approver has enough tokens | |
require(_tokens <= ( | |
(allowed[_from][msg.sender] > transferred[_from][msg.sender]) ? | |
allowed[_from][msg.sender].sub(transferred[_from][msg.sender]) : 0) | |
); // Prevent token transfer more than allowance | |
balances[_from] = balances[_from].sub(_tokens); | |
transferred[_from][msg.sender] = transferred[_from][msg.sender].add(_tokens); | |
balances[_to] = balances[_to].add(_tokens); | |
emit Transfer(_from, _to, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// It helps to give permission to another address to spend tokens on your behalf. | |
// Allow _spender to withdraw from your account, multiple times, up to the _tokens amount. | |
// If this function is called again it overwrites the current allowance with _tokens. | |
// ----------------------------------------------------------------------------- | |
function approve(address _spender, uint256 _tokens) public returns (bool success) { | |
require(_spender != address(0)); | |
require(_spender != msg.sender); | |
require(balances[msg.sender] >= _tokens); | |
allowed[msg.sender][_spender] = _tokens; | |
emit Approval(msg.sender, _spender, _tokens); | |
return true; | |
} | |
// ----------------------------------------------------------------------------- | |
// Returns the amount of tokens approved by the owner that can be | |
// transferred to the spender's account. In other word, how many tokens we gave | |
// permission to another address to spend | |
// ----------------------------------------------------------------------------- | |
function allowance(address _tokenOwner, address _spender) public view returns (uint256 tokens) { | |
return allowed[_tokenOwner][_spender]; | |
} | |
function moved(address _tokenOwner, address _spender) public view returns (uint256 tokens) { | |
return transferred[_tokenOwner][_spender]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.2; | |
/** | |
* For new ERC20 token deployments: | |
* 1- Install MetaMask Chrome/Firefox extension. | |
* 2- Connect MetaMask to Rinkeby Testnet (or your private chain). | |
* 3- Run RemixIDE and set environment="Injected Web3". | |
* 4- Copy and past this code to RemixIDE. | |
* 5- Deploy the token (EST contract) on the blockchain. | |
* 6- Use MetaMask for importing the token and interacting with it. | |
*/ | |
/** | |
* ERC20 interface | |
* https://theethereum.wiki/w/index.php/ERC20_Token_Standard | |
*/ | |
contract ERC20 { | |
function totalSupply() external view returns (uint256); | |
function balanceOf(address _account) external view returns (uint256); | |
function transfer(address _to, uint256 _tokens) external returns (bool); | |
function approve(address _spender, uint256 _tokens) external returns (bool); | |
function transferFrom(address _from, address _to, uint256 _tokens) external returns (bool); | |
function allowance(address _account, address _spender) external view returns (uint256); | |
event Transfer(address indexed _from, address indexed _to, uint256 _tokens); | |
event Approval(address indexed _tokenOwner, address indexed _spender, uint256 _tokens); | |
} | |
/** | |
* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol | |
* @dev Wrappers over Solidity's arithmetic operations with added overflow checks. | |
* | |
* Arithmetic operations in Solidity wrap on overflow. This can easily result | |
* in bugs, because programmers usually assume that an overflow raises an | |
* error, which is the standard behavior in high level programming languages. | |
* `SafeMath` restores this intuition by reverting the transaction when an | |
* operation overflows.Using this library instead of the unchecked operations | |
* eliminates an entire class of bugs, so it's recommended to use it always. | |
*/ | |
library SafeMath { | |
/** | |
* @dev Returns the addition of two unsigned integers, reverting on overflow. | |
* | |
* Counterpart to Solidity's `+` operator. | |
* | |
* Requirements: | |
* - Addition cannot overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
require(c >= a, "SafeMath: addition overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the subtraction of two unsigned integers, reverting on | |
* overflow (when the result is negative). | |
* | |
* Counterpart to Solidity's `-` operator. | |
* | |
* Requirements: | |
* - Subtraction cannot overflow. | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b <= a, "SafeMath: subtraction overflow"); | |
uint256 c = a - b; | |
return c; | |
} | |
/** | |
* @dev Returns the multiplication of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `*` operator. | |
* | |
* Requirements: | |
* - Multiplication cannot overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) { | |
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
uint256 c = a * b; | |
require(c / a == b, "SafeMath: multiplication overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the integer division of two unsigned integers. Reverts on | |
* division by zero. The result is rounded towards zero. | |
* | |
* Counterpart to Solidity's `/` operator. Note: this function uses a | |
* `revert` opcode (which leaves remaining gas untouched) while Solidity | |
* uses an invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// Solidity only automatically asserts when dividing by 0 | |
require(b > 0, "SafeMath: division by zero"); | |
uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return c; | |
} | |
/** | |
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), | |
* Reverts when dividing by zero. | |
* | |
* Counterpart to Solidity's `%` operator. This function uses a `revert` | |
* opcode (which leaves remaining gas untouched) while Solidity uses an | |
* invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function mod(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b != 0, "SafeMath: modulo by zero"); | |
return a % b; | |
} | |
} | |
/** | |
* Concordia University | |
* Montreal, Canada | |
* INSE6610 project : Summer 2019 | |
* On Secure Ethereum Token | |
*/ | |
contract EST is ERC20{ | |
using SafeMath for uint256; // Using SafeMath to mitigate integer overflow | |
string public constant name = "Ethereum Secure Token"; // Name of the token | |
string public constant symbol = "EST"; // Token symbol | |
uint8 public exchangeRate = 100; // 1 ETH = 100 tokens | |
uint256 private decimals = 10 ** 18; // Divisible to 18 decimal places | |
mapping(address => mapping (address => uint256)) private allowed; // Allowed token to transfer by spender | |
mapping(address => mapping (address => uint256)) private transferred; // Transferred tokens by spender | |
mapping(address => uint256) balances; // Balance of token holders | |
address payable private owner = address(0); // Owner of the token | |
uint256 private _totalSupply = 100000000; // Control economy of the token | |
// Log events when buying/selling tokens or sending/withdrawing ETH | |
event LogBuy(address indexed _buyer, uint256 _wei, address indexed _owner, uint256 _tokens); | |
event LogSell(address indexed _seller, uint256 _tokens, address indexed _contract, uint256 _wei, address indexed _owner); | |
event LogReceived(address indexed _sender, uint256 _wei); | |
event LogWithdrawal(address indexed _from, address _contract, uint256 _wei, address indexed _to); | |
bool private locked = false; // Lock variable to mitigate re-entrancy attack | |
/** | |
* Accepts Ether and logs an event | |
*/ | |
function() external payable{ | |
emit LogReceived(msg.sender, msg.value); // Logs sender of ETH (2300 max gas) | |
} | |
/** | |
* Token constructor | |
*/ | |
constructor() public { | |
owner = msg.sender; // Owner of the contract | |
balances[owner] = _totalSupply; // Assigning initial tokens to the owner | |
emit Transfer(address(0), owner, _totalSupply); // Logs transfered tokens to the owner | |
} | |
/** | |
* Returns total amount of token in circulation | |
*/ | |
function totalSupply() public view returns (uint256 tokens) { | |
return _totalSupply; // Total supply of the token | |
} | |
/** | |
* Get the token balance for an address | |
*/ | |
function balanceOf(address _tokenHolder) public view returns (uint256 tokens) { | |
return balances[_tokenHolder]; // Balance of token holder | |
} | |
/** | |
* Transfer the balance (value) from owner's account to another account | |
*/ | |
function transfer(address _to, uint256 _tokens) public returns (bool success) { | |
require(_tokens > 0); // Check for more than zero token | |
require(balances[msg.sender] >= _tokens); // Check if the sender has enough | |
require(balances[_to] + _tokens >= balances[_to]); // Check for overflows | |
balances[msg.sender] = balances[msg.sender].sub(_tokens); // Subtract from the sender | |
balances[_to] = balances[_to].add(_tokens); // Add the same to the recipient | |
emit Transfer(msg.sender, _to, _tokens); | |
return true; | |
} | |
/** | |
* Special type of Transfer and make it possible to give permission to another address | |
* to spend token on your behalf. | |
* It sends _tokens amount of tokens from address _from to address _to | |
* The transferFrom method is used for a withdraw work-flow, allowing contracts to send | |
* tokens on your behalf, for example to "deposit" to a contract address and/or to charge | |
* fees in sub-currencies; the command should fail unless the _from account has | |
* deliberately authorized the sender of the message via some mechanism | |
*/ | |
function transferFrom(address _from, address _to, uint256 _tokens) public returns (bool success) { | |
require(_to != address(0)); // Receiver is valid? | |
require(balances[_from] >= _tokens); // Checks if approver has enough tokens | |
require(_tokens <= ( // Mitigates multiple Withdrawal Attack | |
(allowed[_from][msg.sender] > transferred[_from][msg.sender]) ? | |
allowed[_from][msg.sender].sub(transferred[_from][msg.sender]) : 0) | |
); // Prevent token transfer more than allowance | |
balances[_from] = balances[_from].sub(_tokens); // Decrease balance of approver | |
transferred[_from][msg.sender] = transferred[_from][msg.sender].add(_tokens); // Tracks transferred tokens | |
balances[_to] = balances[_to].add(_tokens); // Increases balance of spender | |
emit Transfer(_from, _to, _tokens); // Logs transferred tokens | |
return true; | |
} | |
/** | |
* It helps to give permission to another address to spend tokens on your behalf. | |
* Allow _spender to withdraw from your account, multiple times, up to the _tokens amount. | |
* If this function is called again it overwrites the current allowance with _tokens. | |
*/ | |
function approve(address _spender, uint256 _tokens) public returns (bool success) { | |
require(_spender != address(0)); // Is address valid? | |
require(_spender != msg.sender); // Spender cannot approve himself | |
require(balances[msg.sender] >= _tokens); // Approve has enough tokens? | |
allowed[msg.sender][_spender] = _tokens; // Sets allowance of the spender | |
emit Approval(msg.sender, _spender, _tokens); // Logs approved tokens | |
return true; | |
} | |
/** | |
* Returns the amount of tokens approved by the owner that can be | |
* transferred to the spender's account. In other word, how many tokens we gave | |
* permission to another address to spend | |
*/ | |
function allowance(address _tokenHolder, address _spender) public view returns (uint256 tokens) { | |
return allowed[_tokenHolder][_spender]; // returns allowance of _spender | |
} | |
/** | |
* Transferring ETH to the seller of the token | |
* If it was not successful, it will revert everything | |
*/ | |
function sell(uint256 _tokens) public returns(bool success) | |
{ | |
require(_tokens > 0); // Is there any token to sell? | |
require(balances[msg.sender] >= _tokens); // Seller has enough tokens? | |
require(!locked); // Lock=false -> no recursive call -> safe to proceed | |
locked = true; // Sets lock=true to mitigate re-entrancy attack | |
uint256 _wei = _tokens.div(exchangeRate).mul(decimals); // Token to ETH and then ETH to Wei | |
if (address(this).balance >= _wei) // Contract has enough Wei to send? | |
{ | |
msg.sender.transfer(_wei); // Transferring Wei | |
balances[msg.sender] = balances[msg.sender].sub(_tokens); // Decreasing tokens of seller | |
balances[owner] = balances[owner].add(_tokens); // Increasing tokens of owner | |
emit LogSell(msg.sender, _tokens, address(this), _wei, owner); | |
success = true; // Seller sold _tokens to owner and Contract paid _wei | |
} | |
else | |
{ | |
emit LogSell(msg.sender, 0, address(this), 0, owner); // Logs failed transfer (zero) | |
success = false; | |
} | |
locked = false; // Unlocks the function | |
return success; | |
} | |
/** | |
* Transferring ETH to the address that is specified by the owner | |
* Only owner of the contract can call this function | |
*/ | |
function send(address payable _to, uint256 _eth) public onlyOwner returns(bool success){ | |
uint256 _wei = _eth.mul(decimals); // ETH to Wei | |
require(address(this).balance >= _wei); // Contract has enough ETH? | |
_to.transfer(_wei); // Transferring Wei to _to | |
emit LogWithdrawal(owner, address(this), _wei, _to); | |
return true; // Owner requested the Contract to send _wei to _to | |
} | |
/** | |
* Buying token by transferring ETH | |
*/ | |
function buy() public payable returns(bool success){ | |
require(msg.sender != owner); // Token owner cannot be as seller and buyer | |
uint256 _eth = msg.value.div(decimals); // Wei to ETH | |
uint256 _tokens = _eth.mul(exchangeRate); // ETH to Token | |
require(balances[owner] >= _tokens); // Owner has enough tokens? | |
balances[msg.sender] = balances[msg.sender].add(_tokens); // Increasing token balance of buyer | |
balances[owner] = balances[owner].sub(_tokens); // Decreasing token balance of owner | |
emit LogBuy(msg.sender, msg.value, owner, _tokens); // Buyer sent _wei and Owner sold _tokens | |
return true; | |
} | |
/** | |
* Returns ETH balance of the Contract to the contract owner | |
*/ | |
function contractBalance() public view onlyOwner returns(uint256 eth){ | |
return address(this).balance.div(decimals); // Wei to ETH | |
} | |
/** | |
* Checks if the caller is contract owner | |
*/ | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.0; | |
import './TokenXFT.sol'; | |
contract OrderBook{ | |
struct OrderStruct{ | |
uint256 Volume; // | |
uint256 Price; //in Wei | |
uint8 Type; //1=Ask, 2=Bid | |
uint8 Mode; //9=Canceled, 8=Confirmed | |
uint8 Status; //0=Inactive, 1=Active, 2=Can be reused | |
uint8 MarketID; //1=Privately arranged, 2=Broker, 3=Exchange, 4=Call Market | |
uint256 MatchedID; // | |
address Creator; //Address of order Creator | |
} | |
TokenXFT xft = TokenXFT(0x381fe99Dc2C6825014679F5C3089b8ACD33b0aEA); | |
address owner; | |
mapping (uint256 => OrderStruct) private Orders; | |
//mapping (uint256 => bytes) private OrdersInBytes; | |
//mapping (uint8 => uint256) private upper; | |
//mapping (uint8 => uint256) private lower; | |
uint8 public transactionFee = 2; | |
uint256 totalOrders = 0; | |
mapping (uint8 => uint256) private callPrice; | |
mapping (uint8 => uint256) private tradable; | |
mapping (uint8 => uint256) private imbalance; | |
constructor() public{ | |
owner = msg.sender; | |
} | |
/*function addBulkOrders(bytes _order) public{ | |
OrdersInBytes[totalOrders] = _order; | |
Orders[totalOrders] = BytesToOrderStruct(_order); | |
totalOrders++; | |
emit OrderOperation(msg.sender, totalOrders, "ADD"); | |
}*/ | |
function addOrder(uint256 _volume, uint256 _price, uint8 _type, uint8 _mode, uint8 _status, uint8 _marketID, uint256 _matchedID, address _creator) public{ | |
Orders[totalOrders] = OrderStruct(_volume, _price, _type, _mode, _status, _marketID, _matchedID, ((msg.sender == owner) ? _creator : msg.sender)); | |
totalOrders++; | |
emit OrderOperation(msg.sender, totalOrders, "ADD"); | |
} | |
function cancelOrder(uint256 _index) public returns(bool success){ | |
require((msg.sender == Orders[_index].Creator) || (msg.sender == owner)); | |
require(_index < totalOrders); | |
Orders[_index].Status = 0; | |
Orders[_index].Mode = 9; | |
emit OrderOperation(msg.sender, _index, "CANCEL"); | |
return true; | |
} | |
function getOrder(uint256 _index) public view returns(uint256 Volume, uint256 Price, uint8 Type, uint8 Mode, uint8 Status, uint8 MarketID, uint256 MatchedID, address Creator){ | |
require(_index < totalOrders); | |
OrderStruct memory Order = Orders[_index]; | |
return (Order.Volume, Order.Price, Order.Type, Order.Mode, Order.Status, Order.MarketID, Order.MatchedID, Order.Creator); | |
} | |
function setOrder(uint256 _index, uint256 _volume, uint256 _price, uint8 _type, uint8 _mode, uint8 _status, uint8 _marketID, uint256 _matchedID, address _creator) public returns (bool success){ | |
OrderStruct memory Order = OrderStruct(_volume, _price, _type, _mode, _status, _marketID, _matchedID, ((msg.sender == owner) ? _creator : msg.sender)); | |
require((msg.sender == Order.Creator) || (msg.sender == owner)); | |
Orders[_index] = Order; | |
emit OrderOperation(msg.sender, _index, "SET"); | |
return true; | |
} | |
function reuseOrders() public onlyOwner { | |
for(uint256 i = 0; i < totalOrders; i++){ | |
if (Orders[i].Status == 0){ | |
Orders[i] = OrderStruct(0, 0, 0, 0, 2, 0, 0, 0x0); | |
} | |
} | |
} | |
function findReusableOrder() private view returns(uint256 _index){ | |
for(uint256 i = 0; i < totalOrders; i++){ | |
if (Orders[i].Status == 2){ | |
return i; | |
} | |
} | |
return 0; | |
} | |
/*function takeOrder(uint256 _index, address _reciever, uint256 _tokens) payable public returns(bool success){ | |
require(msg.value > 0); | |
uint256 deduction = 0; | |
/*deduction = (msg.value * transactionFee) / 100; | |
owner.transfer(deduction); // Contract sends percentage of ETH to the owner as fee | |
emit TransferETH(owner, _index, deduction);*/ | |
/*uint256 value = msg.value - deduction; | |
_reciever.transfer(value); // Contract sends ETH to _reciever (requested by sender) | |
emit TransferETH(_reciever, _index, value); | |
xft.transferFrom(_reciever, msg.sender, _tokens); | |
emit TransferXFT(_reciever, msg.sender, _tokens); | |
return true; | |
}*/ | |
function getNumOfOrders() public view returns(uint256){ | |
return totalOrders; | |
} | |
function setNumOfOrders(uint256 _totalOrders) public onlyOwner{ | |
totalOrders = _totalOrders; | |
emit OrderOperation(msg.sender, _totalOrders, "TOTAL"); | |
} | |
function confirmMatchedID(uint8 _marketID, uint256 _matchedID) private{ | |
for(uint256 i = 0; i < totalOrders; i++) | |
{ | |
if (!isValidOrder(i, _marketID)) { continue; } | |
Orders[i].Mode = (Orders[i].MatchedID == _matchedID) ? 8 : 0; | |
} | |
} | |
function setMatchedID(uint8 _marketID, uint256 _matchedID) private{ | |
for(uint256 i = 0; i < totalOrders; i++) | |
{ | |
if (!isValidOrder(i, _marketID)) { continue; } | |
Orders[i].MatchedID = (Orders[i].Mode == 8) ? _matchedID : 0; | |
} | |
} | |
function matchOrders(uint8 _marketID) public{ | |
uint256 matchedID = 0; | |
callPrice[_marketID] = 0; | |
tradable[_marketID] = 0; | |
imbalance[_marketID] = 0; | |
OrderStruct memory Orderi; | |
OrderStruct memory Orderj; | |
for(uint256 i = 0; i < totalOrders; i++) | |
{ | |
Orderi = Orders[i]; | |
//Looks for the first Bid (Type=2) and omits inactive orders (status=0) | |
if (Orderi.Type == 1 || Orderi.Price == callPrice[_marketID]) { continue; } | |
if (!isValidOrder(i, _marketID)) { continue; } | |
uint256 totalAsks = 0; | |
uint256 totalBids = 0; | |
for(uint256 j = 0; j < totalOrders; j++) | |
{ | |
if (!isValidOrder(j, _marketID)) { continue;} | |
Orderj = Orders[j]; | |
//Aggregates Asks at the candidate price | |
if (Orderj.Type == 1) | |
{ | |
if (Orderj.Price <= Orderi.Price) | |
{ | |
totalAsks += Orderj.Volume; | |
Orders[j].MatchedID = i; | |
continue; | |
} | |
} | |
//Aggregates Bids at the candidate price | |
if (Orderj.Type == 2) | |
{ | |
if (Orderj.Price >= Orderi.Price) | |
{ | |
totalBids += Orderj.Volume; | |
Orders[j].MatchedID = i; | |
} | |
} | |
} | |
// Calculates max tradable volume and imbalance (for each call price candidate) | |
uint256 maxVolume = (totalAsks > totalBids) ? totalBids : totalAsks; | |
uint256 minImbalance = (totalAsks > totalBids) ? totalAsks - totalBids : totalBids - totalAsks; | |
//This price can maximizes the tradable volume? | |
if ((tradable[_marketID] < maxVolume) || (tradable[_marketID] == maxVolume && minImbalance < imbalance[_marketID])) | |
{ | |
matchedID = i; | |
confirmMatchedID(_marketID, matchedID); //Set Mode = 8 as confirmed MatchedID | |
callPrice[_marketID] = Orderi.Price; | |
tradable[_marketID] = maxVolume; | |
imbalance[_marketID] = minImbalance; | |
//emit CallPriceCandidate(callPrice[_marketID], tradable[_marketID], imbalance[_marketID]); | |
} | |
} | |
setMatchedID(_marketID, matchedID); //Revert back any changes made by Candidates | |
emit CallPrice(callPrice[_marketID], tradable[_marketID], imbalance[_marketID]); | |
} | |
function isValidOrder(uint256 _index, uint8 _marketID) private view returns (bool){ | |
OrderStruct memory Order = Orders[_index]; | |
return (Order.MarketID == _marketID && Order.Status != 0 && Order.Mode != 9); | |
} | |
function setTransactionFee(uint8 _newFee) onlyOwner public{ | |
transactionFee = _newFee; | |
} | |
function getOwner() public view returns (address){ | |
return owner; | |
} | |
function getCallPrice(uint8 _marketID) public view returns (uint256){ | |
return callPrice[_marketID]; | |
} | |
function getTradable(uint8 _marketID) public view returns (uint256){ | |
return tradable[_marketID]; | |
} | |
function getImbalance(uint8 _marketID) public view returns (uint256){ | |
return imbalance[_marketID]; | |
} | |
modifier onlyOwner { | |
assert(owner == msg.sender); | |
_; | |
} | |
event OrderOperation(address _addr, uint256 _index, string _operation); | |
event CallPriceCandidate(uint256 _price, uint256 _tradable, uint256 _imbalance); | |
event CallPrice(uint256 _price, uint256 _tradable, uint256 _imbalance); | |
event TransferETH(address _addr, uint256 _index, uint256 _value); | |
event TransferXFT(address _from, address _to, uint256 _tokens); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.24; | |
contract Order { | |
struct OrderStruct{ | |
uint256 Volume; // | |
uint256 Price; // | |
uint8 Type; //1=Ask, 2=Bid | |
uint8 Mode; // | |
uint8 Status; //0=Inactive, 1=Active, 2=Can be reused | |
uint8 MarketID; //1=Privately arranged, 2=Broker, 3=Exchange, 4=Call Market | |
uint256 MatchedID; // | |
address Creator; //Address of order Creator | |
} | |
uint256 internal StructSize = 120; // 120=sizeof(Volume)+sizeof(Price)+...+sizeof(Creator) | |
function OrderStructToBytes(OrderStruct) internal returns (bytes); | |
function BytesToOrderStruct(bytes) internal returns (OrderStruct); | |
} | |
contract Orders is Order{ | |
function OrderStructToBytes(OrderStruct _order) internal returns (bytes){ | |
//uint strSize = bytes(_order.Terms).length; | |
bytes memory buffer = new bytes(StructSize); | |
uint256 Creator = uint256(_order.Creator); | |
uint i = 0; | |
uint pointer=0; | |
for (i=0; i<32 ; i++){ buffer[pointer++]=byte(_order.Volume>>(8*i)&uint256(255)); } | |
for (i=0; i<32 ; i++){ buffer[pointer++]=byte(_order.Price>>(8*i)&uint256(255)); } | |
for (i=0; i<1 ; i++){ buffer[pointer++]=byte(_order.Type>>(8*i)&uint8(255)); } | |
for (i=0; i<1 ; i++){ buffer[pointer++]=byte(_order.Mode>>(8*i)&uint8(255)); } | |
for (i=0; i<1 ; i++){ buffer[pointer++]=byte(_order.Status>>(8*i)&uint8(255)); } | |
for (i=0; i<1 ; i++){ buffer[pointer++]=byte(_order.MarketID>>(8*i)&uint8(255)); } | |
for (i=0; i<32 ; i++){ buffer[pointer++]=byte(_order.MatchedID>>(8*i)&uint256(255)); } | |
for (i=0; i<20 ; i++){ buffer[pointer++]=byte(Creator>>(8*i)&uint256(255)); } | |
//for (i=0; i<strSize; i++){ buffer[pointer++]=bytes(_order.Terms)[i]; } | |
return buffer; | |
} | |
function BytesToOrderStruct(bytes _bytes) internal returns (OrderStruct _out){ | |
//uint strSize = _bytes.length-StructSize; | |
uint256 Creator; | |
uint i = 0; | |
uint pointer=0; | |
for (i=0; i<32; i++){ _out.Volume^=uint256(_bytes[pointer++])<<8*i; } | |
for (i=0; i<32; i++){ _out.Price^=uint256(_bytes[pointer++])<<8*i; } | |
for (i=0; i<1; i++){ _out.Type^=uint8(_bytes[pointer++])<<8*i; } | |
for (i=0; i<1; i++){ _out.Mode^=uint8(_bytes[pointer++])<<8*i; } | |
for (i=0; i<1; i++){ _out.Status^=uint8(_bytes[pointer++])<<8*i; } | |
for (i=0; i<1; i++){ _out.MarketID^=uint8(_bytes[pointer++])<<8*i; } | |
for (i=0; i<32; i++){ _out.MatchedID^=uint256(_bytes[pointer++])<<8*i; } | |
for (i=0; i<20; i++){ Creator^=uint256(_bytes[pointer++])<<8*i; } | |
_out.Creator = address(Creator); | |
/*bytes memory terms = new bytes(strSize); | |
for (i=0; i<strSize; i++){ terms[i]=_bytes[pointer++]; } | |
_out.Terms = string(terms);*/ | |
return _out; | |
} | |
} | |
contract OrderTest is Orders{ | |
OrderStruct public inStruct; | |
OrderStruct public outStruct; | |
bytes public bytesStruct; | |
constructor() public { | |
inStruct = OrderStruct(100, 98, 2, 9, 1, 4, 0, 0x123); | |
bytesStruct = OrderStructToBytes(inStruct); | |
outStruct = BytesToOrderStruct(bytesStruct); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol | |
// ----------------------------------------------------------------------------------------- | |
pragma solidity ^0.5.0; | |
/** | |
* @dev Wrappers over Solidity's arithmetic operations with added overflow | |
* checks. | |
* | |
* Arithmetic operations in Solidity wrap on overflow. This can easily result | |
* in bugs, because programmers usually assume that an overflow raises an | |
* error, which is the standard behavior in high level programming languages. | |
* `SafeMath` restores this intuition by reverting the transaction when an | |
* operation overflows. | |
* | |
* Using this library instead of the unchecked operations eliminates an entire | |
* class of bugs, so it's recommended to use it always. | |
*/ | |
library SafeMath { | |
/** | |
* @dev Returns the addition of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `+` operator. | |
* | |
* Requirements: | |
* - Addition cannot overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
require(c >= a, "SafeMath: addition overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the subtraction of two unsigned integers, reverting on | |
* overflow (when the result is negative). | |
* | |
* Counterpart to Solidity's `-` operator. | |
* | |
* Requirements: | |
* - Subtraction cannot overflow. | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b <= a, "SafeMath: subtraction overflow"); | |
uint256 c = a - b; | |
return c; | |
} | |
/** | |
* @dev Returns the multiplication of two unsigned integers, reverting on | |
* overflow. | |
* | |
* Counterpart to Solidity's `*` operator. | |
* | |
* Requirements: | |
* - Multiplication cannot overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) { | |
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
uint256 c = a * b; | |
require(c / a == b, "SafeMath: multiplication overflow"); | |
return c; | |
} | |
/** | |
* @dev Returns the integer division of two unsigned integers. Reverts on | |
* division by zero. The result is rounded towards zero. | |
* | |
* Counterpart to Solidity's `/` operator. Note: this function uses a | |
* `revert` opcode (which leaves remaining gas untouched) while Solidity | |
* uses an invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// Solidity only automatically asserts when dividing by 0 | |
require(b > 0, "SafeMath: division by zero"); | |
uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return c; | |
} | |
/** | |
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), | |
* Reverts when dividing by zero. | |
* | |
* Counterpart to Solidity's `%` operator. This function uses a `revert` | |
* opcode (which leaves remaining gas untouched) while Solidity uses an | |
* invalid opcode to revert (consuming all remaining gas). | |
* | |
* Requirements: | |
* - The divisor cannot be zero. | |
*/ | |
function mod(uint256 a, uint256 b) internal pure returns (uint256) { | |
require(b != 0, "SafeMath: modulo by zero"); | |
return a % b; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.10; | |
import './SafeMath.sol'; | |
/** | |
* Integer overflow demonstration | |
*/ | |
contract overflowDemo { | |
uint256 public a = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; | |
uint256 public b = 0x0000000000000000000000000000000000000000000000000000000000000001; | |
uint256 public c; | |
constructor() public { | |
c = 0x3; | |
} | |
function a_plus_b() public{ | |
c = a + b; | |
} | |
} | |
contract overflowDemoSafe { | |
using SafeMath for uint256; | |
uint256 public a = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; | |
uint256 public b = 0x0000000000000000000000000000000000000000000000000000000000000001; | |
uint256 public c; | |
constructor() public { | |
c = 0x3; | |
} | |
function a_plus_b() public{ | |
c = a.add(b); | |
} | |
} | |
/** | |
* UnderFlow exploit demonstration | |
*/ | |
contract underflowDemo { | |
using SafeMath for uint256; | |
uint256 public a = 0x0000000000000000000000000000000000000000000000000000000000000000; // 64 hex values => 64 x 4 = 256 bits | |
uint256 public b = 0x0000000000000000000000000000000000000000000000000000000000000001; | |
uint256 public c; | |
constructor() public { | |
c = 0x3; | |
} | |
function a_minus_b_default() public{ | |
c = a - b; | |
} | |
function a_minus_b_safe() public{ | |
c = a.sub(b); | |
} | |
} | |
contract multiplyDemo{ | |
uint256 public a = 0x8000000000000000000000000000000000000000000000000000000000000000; | |
uint256 public b = 0x2; | |
uint256 public c; | |
constructor() public { | |
c = 0x3; | |
} | |
function a_multiply_b() public returns (bool){ | |
c = a * b; | |
return (c == 0) ? true : false; | |
} | |
} | |
contract multiplyDemoSafe{ | |
using SafeMath for uint256; | |
uint256 public a = 0x8000000000000000000000000000000000000000000000000000000000000000; | |
uint256 public b = 0x2; | |
uint256 public c; | |
constructor() public { | |
c = 0x3; | |
} | |
function a_multiply_b() public returns (bool){ | |
c = a.mul(b); | |
return (c == 0) ? true : false; | |
} | |
} | |
contract test{ | |
uint256 public a = 7000000000000000000000000000; | |
uint256 public b = 0x8000000000000000000000000000000000000000000000000000000000000000; | |
uint256 public c; | |
constructor() public{ | |
c = b /a; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment