Skip to content

Commit

Permalink
[Docs] add examples of ERC contract standard checker
Browse files Browse the repository at this point in the history
  • Loading branch information
hydai committed Jul 13, 2018
1 parent dc8c3b9 commit 68e1126
Show file tree
Hide file tree
Showing 7 changed files with 527 additions and 1 deletion.
9 changes: 9 additions & 0 deletions docs/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ Rule Engine
-----------

- `Lity rule engine v1.0 spec <_static/files/lity-rule-engine-spec-v1-0.pdf>`_

ERC Contract Standard Checker
-----------------------------

- `ERC20 Checker <erc-contract-standard-checker/erc20-checker>`
- `ERC223 Checker <erc-contract-standard-checker/erc223-checker>`
- `ERC721 Checker <erc-contract-standard-checker/erc721-checker>`
- `ERC827 Checker <erc-contract-standard-checker/erc827-checker>`
- `ERC884 Checker <erc-contract-standard-checker/erc884-checker>`
2 changes: 1 addition & 1 deletion docs/eni-tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Run with `ABCDE` as input to your contract.
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000054142434445000000000000000000000000000000000000000000000000000000
Accroding to the ABI of Ethereum contracts, the output could be decode as string `EDCBA`.
According to the ABI of Ethereum contracts, the output could be decode as string `EDCBA`.

.. code:: bash
Expand Down
74 changes: 74 additions & 0 deletions docs/erc-contract-standard-checker/erc20-checker.rst
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).
181 changes: 181 additions & 0 deletions docs/erc-contract-standard-checker/erc223-checker.rst
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).
80 changes: 80 additions & 0 deletions docs/erc-contract-standard-checker/erc721-checker.rst
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).

0 comments on commit 68e1126

Please sign in to comment.