parent
040d15ca0b
commit
6125e01c83
@ -0,0 +1,61 @@ |
||||
var name = 'ERC20: ' |
||||
var desc = 'Decimal should be uint8' |
||||
var categories = require('./categories') |
||||
var common = require('./staticAnalysisCommon') |
||||
var AbstractAst = require('./abstractAstView') |
||||
|
||||
function erc20Decimals () { |
||||
this.abstractAst = new AbstractAst() |
||||
this.visit = this.abstractAst.build_visit( |
||||
(node) => false |
||||
) |
||||
this.report = this.abstractAst.build_report(report) |
||||
} |
||||
|
||||
erc20Decimals.prototype.visit = function () { throw new Error('erc20Decimals.js no visit function set upon construction') } |
||||
|
||||
erc20Decimals.prototype.report = function () { throw new Error('erc20Decimals.js no report function set upon construction') } |
||||
|
||||
function report (contracts, multipleContractsWithSameName) { |
||||
var warnings = [] |
||||
|
||||
contracts.forEach((contract) => { |
||||
let contractAbiSignatures = contract.functions.map((f) => common.helpers.buildAbiSignature(common.getFunctionDefinitionName(f.node), f.parameters)) |
||||
|
||||
if (isERC20(contractAbiSignatures)) { |
||||
let decimalsVar = contract.stateVariables.filter((stateVar) => common.getDeclaredVariableName(stateVar) === 'decimals' && (common.getDeclaredVariableType(stateVar) !== 'uint8' || stateVar.attributes.visibility !== 'public')) |
||||
let decimalsFun = contract.functions.filter((f) => common.getFunctionDefinitionName(f.node) === 'decimals' && |
||||
( |
||||
(f.returns.length === 0 || f.returns.length > 1) || |
||||
(f.returns.length === 1 && (f.returns[0].type !== 'uint8' || f.node.attributes.visibility !== 'public')) |
||||
) |
||||
) |
||||
|
||||
if (decimalsVar.length > 0 || decimalsFun.length > 0) { |
||||
warnings.push({ |
||||
warning: 'ERC20 Contracts decimals function should have uint8 as return type', |
||||
location: null, |
||||
more: 'https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md' |
||||
}) |
||||
} |
||||
} |
||||
}) |
||||
|
||||
return warnings |
||||
} |
||||
|
||||
function isERC20 (funSignatures) { |
||||
return funSignatures.includes('totalSupply()') && |
||||
funSignatures.includes('balanceOf(address)') && |
||||
funSignatures.includes('transfer(address,uint256)') && |
||||
funSignatures.includes('transferFrom(address,address,uint256)') && |
||||
funSignatures.includes('approve(address,uint256)') && |
||||
funSignatures.includes('allowance(address,address)') |
||||
} |
||||
|
||||
module.exports = { |
||||
name: name, |
||||
description: desc, |
||||
category: categories.ERC, |
||||
Module: erc20Decimals |
||||
} |
@ -1,5 +1,6 @@ |
||||
module.exports = { |
||||
SECURITY: {displayName: 'Security', id: 'SEC'}, |
||||
GAS: {displayName: 'Gas & Economy', id: 'GAS'}, |
||||
MISC: {displayName: 'Miscellaneous', id: 'MISC'} |
||||
MISC: {displayName: 'Miscellaneous', id: 'MISC'}, |
||||
ERC: {displayName: 'ERC', id: 'ERC'} |
||||
} |
||||
|
@ -0,0 +1,46 @@ |
||||
|
||||
pragma solidity ^0.4.17; |
||||
contract EIP20 { |
||||
|
||||
uint public decimals = 12; |
||||
|
||||
// optional |
||||
function name() public pure returns (string) { |
||||
return "MYTOKEN"; |
||||
} |
||||
|
||||
// optional |
||||
function symbol() public pure returns (string) { |
||||
return "MT"; |
||||
} |
||||
|
||||
// optional |
||||
//function decimals() internal pure returns (uint8) { |
||||
// return 12; |
||||
//} |
||||
|
||||
function totalSupply() public pure returns (uint256) { |
||||
return 12000; |
||||
} |
||||
|
||||
function balanceOf(address _owner) public pure returns (uint256) { |
||||
return 0; |
||||
} |
||||
|
||||
function transfer(address _to, uint256 _value) public pure returns (bool success) { |
||||
return true; |
||||
} |
||||
|
||||
function transferFrom(address _from, address _to, uint256 _value) public pure returns (bool) { |
||||
return true; |
||||
} |
||||
|
||||
function approve(address _spender, uint256 _value) public pure returns (bool) { |
||||
return true; |
||||
} |
||||
|
||||
function allowance(address _owner, address _spender) public pure returns (uint256) { |
||||
return 0; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue