-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Docs] add examples of ERC contract standard checker
- Loading branch information
Showing
7 changed files
with
527 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
ERC20 Contract Standard Checker | ||
=============================== | ||
|
||
Enable contract standard checker with specific ERC | ||
-------------------------------------------------- | ||
|
||
.. code:: bash | ||
lityc --contract-standard ERC20 <contract file> | ||
Examples | ||
-------- | ||
|
||
- ERC20 Interface (erc20_interface.sol) | ||
|
||
.. code:: solidity | ||
pragma solidity ^0.4.23; | ||
contract ERC20Interface { | ||
function totalSupply() public view returns (uint); | ||
function balanceOf(address tokenOwner) public view returns (uint balance); | ||
function allowance(address tokenOwner, address spender) public view returns (uint remaining); | ||
function transfer(address to, uint tokens) public returns (bool success); | ||
function approve(address spender, uint tokens) public returns (bool success); | ||
function transferFrom(address from, address to, uint tokens) public returns (bool success); | ||
event Transfer(address indexed from, address indexed to, uint tokens); | ||
event Approval(address indexed tokenOwner, address indexed spender, uint tokens); | ||
} | ||
- Expect output | ||
|
||
.. code:: bash | ||
$ lityc --contract-standard ERC20 erc20_interface.sol | ||
erc20_standard.sol:3:1: Info: ERC20Interface is compatible to ERC20. | ||
contract ERC20Interface { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
- ERC20 Interface with wrong mutability (wrong_mutability.sol) | ||
.. code:: solidity | ||
pragma solidity ^0.4.23; | ||
contract ERC20Interface { | ||
function totalSupply() public pure returns (uint); // mutability should be view, not pure | ||
function balanceOf(address tokenOwner) public view returns (uint balance); | ||
function allowance(address tokenOwner, address spender) public view returns (uint remaining); | ||
function transfer(address to, uint tokens) public returns (bool success); | ||
function approve(address spender, uint tokens) public returns (bool success); | ||
function transferFrom(address from, address to, uint tokens) public returns (bool success); | ||
event Transfer(address indexed from, address indexed to, uint tokens); | ||
event Approval(address indexed tokenOwner, address indexed spender, uint tokens); | ||
} | ||
- Expect output | ||
.. code:: bash | ||
$ lityc --contract-standard ERC20 wrong_mutability.sol | ||
wrong_mutability.sol:3:1: Info: Missing 'totalSupply' with type signature 'function () view external returns (uint256)'. ERC20Interface is not compatible to ERC20. | ||
contract ERC20Interface { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
ERC223 Contract Standard Checker | ||
=============================== | ||
|
||
Enable contract standard checker with specific ERC | ||
-------------------------------------------------- | ||
|
||
.. code:: bash | ||
lityc --contract-standard ERC223 <contract file> | ||
Examples | ||
-------- | ||
|
||
- ERC223 Interface (erc223_interface.sol) | ||
|
||
.. code:: solidity | ||
pragma solidity ^0.4.23; | ||
contract ERC223Interface { | ||
function totalSupply() public view returns (uint); | ||
function balanceOf(address tokenOwner) public view returns (uint balance); | ||
function transfer(address to, uint tokens) public returns (bool success); | ||
function transfer(address to, uint tokens, bytes data) public returns (bool success); | ||
event Transfer(address indexed from, address indexed to, uint tokens, bytes data); | ||
} | ||
- Expect output | ||
|
||
.. code:: bash | ||
$ lityc --contract-standard ERC223 erc223_interface.sol | ||
erc223_standard.sol:3:1: Info: ERC223Interface is compatible to ERC223. | ||
contract ERC223Interface { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
- ERC223 Token example (erc223_token.sol) | ||
.. code:: solidity | ||
pragma solidity ^0.4.11; | ||
library SafeMath { | ||
function mul(uint a, uint b) internal pure returns (uint) { | ||
uint c = a * b; | ||
_assert(a == 0 || c / a == b); | ||
return c; | ||
} | ||
function div(uint a, uint b) internal pure returns (uint) { | ||
// _assert(b > 0); // Solidity automatically throws when dividing by 0 | ||
uint c = a / b; | ||
// _assert(a == b * c + a % b); // There is no case in which this doesn't hold | ||
return c; | ||
} | ||
function sub(uint a, uint b) internal pure returns (uint) { | ||
_assert(b <= a); | ||
return a - b; | ||
} | ||
function add(uint a, uint b) internal pure returns (uint) { | ||
uint c = a + b; | ||
_assert(c >= a); | ||
return c; | ||
} | ||
function max64(uint64 a, uint64 b) internal pure returns (uint64) { | ||
return a >= b ? a : b; | ||
} | ||
function min64(uint64 a, uint64 b) internal pure returns (uint64) { | ||
return a < b ? a : b; | ||
} | ||
function max256(uint256 a, uint256 b) internal pure returns (uint256) { | ||
return a >= b ? a : b; | ||
} | ||
function min256(uint256 a, uint256 b) internal pure returns (uint256) { | ||
return a < b ? a : b; | ||
} | ||
function _assert(bool assertion) internal pure { | ||
if (!assertion) { | ||
revert(); | ||
} | ||
} | ||
} | ||
contract ERC223Interface { | ||
function totalSupply() public view returns (uint); | ||
function balanceOf(address tokenOwner) public view returns (uint balance); | ||
function transfer(address to, uint tokens, bytes data) public returns (bool success); | ||
function transfer(address to, uint tokens) public returns (bool success); | ||
event Transfer(address indexed from, address indexed to, uint tokens, bytes data); | ||
} | ||
contract ERC223ReceivingContract { | ||
function tokenFallback(address _from, uint _value, bytes _data) public; | ||
} | ||
contract ERC223Token is ERC223Interface { | ||
using SafeMath for uint; | ||
mapping(address => uint) balances; // List of user balances. | ||
function totalSupply() public view returns (uint) { | ||
return 2**18; | ||
} | ||
function transfer(address _to, uint _value, bytes _data) public returns (bool) { | ||
// Standard function transfer similar to ERC20 transfer with no _data . | ||
// Added due to backwards compatibility reasons . | ||
uint codeLength; | ||
assembly { | ||
// Retrieve the size of the code on target address, this needs assembly . | ||
codeLength := extcodesize(_to) | ||
} | ||
balances[msg.sender] = balances[msg.sender].sub(_value); | ||
balances[_to] = balances[_to].add(_value); | ||
if(codeLength>0) { | ||
ERC223ReceivingContract receiver = ERC223ReceivingContract(_to); | ||
receiver.tokenFallback(msg.sender, _value, _data); | ||
return true; | ||
} | ||
emit Transfer(msg.sender, _to, _value, _data); | ||
return true; | ||
} | ||
function transfer(address _to, uint _value) public returns (bool) { | ||
uint codeLength; | ||
bytes memory empty; | ||
assembly { | ||
// Retrieve the size of the code on target address, this needs assembly . | ||
codeLength := extcodesize(_to) | ||
} | ||
balances[msg.sender] = balances[msg.sender].sub(_value); | ||
balances[_to] = balances[_to].add(_value); | ||
if(codeLength>0) { | ||
ERC223ReceivingContract receiver = ERC223ReceivingContract(_to); | ||
receiver.tokenFallback(msg.sender, _value, empty); | ||
return true; | ||
} | ||
emit Transfer(msg.sender, _to, _value, empty); | ||
return true; | ||
} | ||
function balanceOf(address _owner) public view returns (uint balance) { | ||
return balances[_owner]; | ||
} | ||
} | ||
- Expect output | ||
.. code:: bash | ||
$ lityc --contract-standard ERC223 erc223_token.sol | ||
erc223_token.sol:6:1: Info: Missing 'totalSupply' with type signature 'function () view external returns (uint256)'. SafeMath is not compatible to ERC223. | ||
library SafeMath { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
erc223_token.sol:54:1: Info: ERC223Interface is compatible to ERC223. | ||
contract ERC223Interface { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
erc223_token.sol:65:1: Info: Missing 'totalSupply' with type signature 'function () view external returns (uint256)'. ERC223ReceivingContract is not compatible to ERC223. | ||
contract ERC223ReceivingContract { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
erc223_token.sol:78:1: Info: ERC223Token is compatible to ERC223. | ||
contract ERC223Token is ERC223Interface { | ||
^ (Relevant source part starts here and spans across multiple lines). |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
ERC721 Contract Standard Checker | ||
=============================== | ||
|
||
Enable contract standard checker with specific ERC | ||
-------------------------------------------------- | ||
|
||
.. code:: bash | ||
lityc --contract-standard ERC721 <contract file> | ||
Examples | ||
-------- | ||
|
||
- ERC721 Interface (erc721_interface.sol) | ||
|
||
.. code:: solidity | ||
pragma solidity ^0.4.23; | ||
contract ERC721Interface { | ||
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); | ||
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); | ||
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); | ||
function balanceOf(address _owner) external view returns (uint256); | ||
function ownerOf(uint256 _tokenId) external view returns (address); | ||
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; | ||
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; | ||
function transferFrom(address _from, address _to, uint256 _tokenId) external payable; | ||
function approve(address _approved, uint256 _tokenId) external payable; | ||
function setApprovalForAll(address _operator, bool _approved) external; | ||
function getApproved(uint256 _tokenId) external view returns (address); | ||
function isApprovedForAll(address _owner, address _operator) external view returns (bool); | ||
function supportsInterface(bytes4 interfaceID) external view returns (bool); | ||
} | ||
- Expect output | ||
|
||
.. code:: bash | ||
$ lityc --contract-standard ERC721 erc721_interface.sol | ||
- ERC721 Interface with wrong modification level (wrong_modification_level.sol) | ||
|
||
.. code:: solidity | ||
pragma solidity ^0.4.23; | ||
contract ERC721Interface { | ||
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); | ||
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); | ||
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); | ||
function balanceOf(address _owner) external view returns (uint256); | ||
function ownerOf(uint256 _tokenId) external view returns (address); | ||
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; | ||
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; | ||
function transferFrom(address _from, address _to, uint256 _tokenId) external; // missing payable | ||
function approve(address _approved, uint256 _tokenId) external payable; | ||
function setApprovalForAll(address _operator, bool _approved) external; | ||
function getApproved(uint256 _tokenId) external view returns (address); | ||
function isApprovedForAll(address _owner, address _operator) external view returns (bool); | ||
function supportsInterface(bytes4 interfaceID) external view returns (bool); | ||
} | ||
- Expect output | ||
|
||
.. code:: bash | ||
$ lityc --contract-standard ERC721 wrong_modification_level.sol | ||
wrong_modification_level.sol:3:1: Info: Missing 'transferFrom' with type signature 'function (address,address,uint256) payable external'. ERC721Interface is not compatible to ERC721. | ||
contract ERC721Interface { | ||
^ (Relevant source part starts here and spans across multiple lines). | ||
Oops, something went wrong.