Skip to content
Snippets Groups Projects
Commit 539e0497 authored by POTHURI HARIKA's avatar POTHURI HARIKA
Browse files

Upload New File

parent d56f5882
No related branches found
No related tags found
No related merge requests found
# Analysis of Smart Contract Security Vulnerabilities and Tools ![](https://img.shields.io/badge/-Live-brightgreen)
![](https://img.shields.io/badge/Batch-UG21CYS-lightgreen) ![](https://img.shields.io/badge/Batch-PG21CYS-green) ![](https://img.shields.io/badge/Batch-UG22CYS-lightgreen) ![](https://img.shields.io/badge/Batch-PG21CYS-green) ![](https://img.shields.io/badge/Batch-PhD-darkgreen) ![](https://img.shields.io/badge/-B_RIG-darkgreen)<br/> ![](https://img.shields.io/badge/BlockchainCourse-21CY712-green) ![](https://img.shields.io/badge/-M.Tech_Dissertation-blue) ![](https://img.shields.io/badge/Focus-Smart_Contract_Security-yellow) <br/>
![](https://img.shields.io/badge/Blockchain-Ethereum-blue) <br/>
![](https://img.shields.io/badge/Language-Solidity-blue)
## SOLIDITY_GAS_LIMIT_IN_LOOPS
### Rule Description
<p>
Ethereum is a very resource-constrained environment. Prices per computational step are orders of magnitude higher than with centralized providers. Moreover, Ethereum miners impose a limit on the total number of gas consumed in a block. If <code>array.length</code> is large enough, the function exceeds the block gas limit, and transactions calling it will never be confirmed:
</p>
<pre><code>
for (uint256 i = 0; i < array.length ; i++) {
cosltyFunc();
}
</code></pre>
<p>
This becomes a security issue, if an external actor influences <code>array.length</code>.
E.g., if array enumerates all registered addresses, an adversary can register many addresses, causing the problem described above.
</p>
<p>
Vulnerability type by SmartDec classification: <a href="https://github.com/smartdec/classification#gas-limitations">
Infinite loops</a>.
</p>
### Solidity-Rules
![](https://img.shields.io/badge/Pattern_ID-f6f853-gold) ![](https://img.shields.io/badge/Severity-2-brown)
```
//forStatement
[ <!-- i = 0; -->
expression[1][text()[1] = "="]/expression[2]//numberLiteral/decimalNumber[text()[1] = "0"]
<!-- uint i = 0; -->
or expression[1]/variableDeclaration[text()[1] = "="]/expression//numberLiteral/decimalNumber[text()[1] = "0"]
<!-- uint i; -->
or expression[1]/variableDeclaration[not(text()[1] = "=")]
]
[ <!-- ".length" in condition and base is not in memory -->
condition/expression[matches(text()[1], "&lt;|&lt;=")]/expression[2][text()[1] = ".length"]/expression/primaryExpression/identifier
<!-- and array is neither public or external function argument -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text())]
<!-- nor internal or private function argument with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text())]
<!-- nor copied to local variable with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text())]
<!-- may be a variable in condition and it is ... -->
or condition/expression[matches(text()[1], "&lt;|&lt; =")]/expression[2]/primaryExpression/identifier
[ <!-- new variable with non-memory array length -->
text()[1] = (ancestor::functionDefinition//variableDeclaration[text()[1] = "="]
[expression[text()[1] = ".length"]/expression/primaryExpression/identifier
<!-- and array is neither public or external function argument -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text())]
<!-- nor internal or private function argument with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text())]
<!-- nor copied to local variable with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text())]
]/identifier/text()[1])
<!-- or reused variable with non-memory array length -->
or text()[1] = (ancestor::functionDefinition//expression[text()[1] = "="]
[expression[2][text()[1] = ".length"]/expression/primaryExpression/identifier
<!-- and array is neither public or external function argument -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text())]
<!-- nor internal or private function argument with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text())]
<!-- nor copied to local variable with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text())]
]/expression[1]//identifier/text()[1])
]
]
```
![](https://img.shields.io/badge/Pattern_ID-4b7do5-gold) ![](https://img.shields.io/badge/Severity-1-brown)
```
//forStatement
[ <!-- i = 0; -->
expression[1][text()[1] = "="]/expression[2]//numberLiteral/decimalNumber[text()[1] = "0"]
<!-- uint i = 0; -->
or expression[1]/variableDeclaration[text()[1] = "="]/expression//numberLiteral/decimalNumber[text()[1] = "0"]
<!-- uint i; -->
or expression[1]/variableDeclaration[not(text()[1] = "=")]
]
[ <!-- ".length" in condition and base is in memory -->
condition/expression[matches(text()[1], "&lt;|&lt;=")]/expression[2][text()[1] = ".length"]/expression/primaryExpression/identifier
[ <!-- and array is either public or external function argument -->
text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text()
<!-- or internal or private function argument with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text()
<!-- or copied to local variable with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text()
]
<!-- may be a variable in condition and it is ... -->
or condition/expression[matches(text()[1], "&lt;|&lt;=")]/expression[2]/primaryExpression/identifier
[ <!-- new variable with memory array length -->
text()[1] = (ancestor::functionDefinition//variableDeclaration[text()[1] = "="]
[expression[text()[1] = ".length"]/expression/primaryExpression/identifier
[ <!-- and array is either public or external function argument -->
text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text()
<!-- or internal or private function argument with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text()
<!-- or copied to local variable with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text()
]
]/identifier/text()[1])
<!-- or reused variable with memory array length -->
or text()[1] = (ancestor::functionDefinition//expression[text()[1] = "="]
[expression[2][text()[1] = ".length"]/expression/primaryExpression/identifier
[ <!-- and array is either public or external function argument -->
text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text()
<!-- or internal or private function argument with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text()
<!-- or copied to local variable with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text()
]
]/expression[1]//identifier/text()[1])
]
]
```
![](https://img.shields.io/badge/Pattern_ID-12cf32-gold) ![](https://img.shields.io/badge/Severity-2-brown)
```
forStatement
[
( <!-- either reused variable with .length in pre-condition -->
expression[1][text()[1] = "="]/expression[2][text()[1] = ".length"]/expression/primaryExpression/identifier
<!-- or new variable with .length in pre-condition -->
| expression[1]/variableDeclaration[text()[1] = "="]/expression[text()[1] = ".length"]/expression/primaryExpression/identifier
)
<!-- and array is neither public or external function argument -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text())]
<!-- nor internal or private function argument with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text())]
<!-- nor copied to local variable with memory visibility modifier -->
[not(text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text())]
]
[condition/expression[matches(text()[1], "&gt;|&gt;=")]]
```
![](https://img.shields.io/badge/Pattern_ID-v5j3d9-gold) ![](https://img.shields.io/badge/Severity-1-brown)
```
//forStatement
[
( <!-- either reused variable with .length in pre-condition -->
expression[1][text()[1] = "="]/expression[2][text()[1] = ".length"]/expression/primaryExpression/identifier
<!-- or new variable with .length in pre-condition -->
| expression[1]/variableDeclaration[text()[1] = "="]/expression[text()[1] = ".length"]/expression/primaryExpression/identifier
)
[ <!-- and array is either public or external function argument -->
text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^public$|^external$")] or not(visibleType)]//parameter/identifier/text()
<!-- or internal or private function argument with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition[visibleType[matches(text()[1], "^private$|^internal$")]]//parameter[storageLocation/text() = "memory"]/identifier/text()
<!-- or copied to local variable with memory visibility modifier -->
or text()[1] = ancestor::functionDefinition//variableDeclaration[storageLocation/text() = "memory"]/identifier/text()
]
]
[condition/expression[matches(text()[1], "&gt;|&gt;=")]]
```
![](https://img.shields.io/badge/Pattern_ID-17f23a-gold) ![](https://img.shields.io/badge/Severity-2-brown)
```
//whileStatement/condition
[
not(descendant-or-self::functionCall)
and not(expression/expression/primaryExpression/numberLiteral/decimalNumber)
]
```
![](https://img.shields.io/badge/Pattern_ID-38f6c7-gold) ![](https://img.shields.io/badge/Severity-2-brown)
```
//whileStatement[condition/descendant::functionCall]
```
### Sample Code
```
pragma solidity 0.4.24;
contract GasLimitInLoops {
function foo() pure internal returns (uint) {
return(100);
}
function testWhile() public {
uint x=0;
uint[] memory y;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 38f6c7
while (x < foo()) {
}
while (x > 100) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 17f23a
while (y[5] < x) {
}
}
function testFor(address[] _addr, uint amount) public {
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (uint i = 0; i < _addr.length; i++) {
}
uint n = _addr.length;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < n; i++) {
}
uint m;
m = _addr.length;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < m; i++) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (uint k; k < _addr.length; k++) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS v5j3d9
for (i = _addr.length; i > 0; i--) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS v5j3d9
for (uint j = _addr.length; j > 0; j--) {
}
}
address[] stor;
function testForMemory(address[] memory mem) {
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (uint i = 0; i < mem.length; i++) {
}
uint n = mem.length;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < n; i++) {
}
uint m;
m = mem.length;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < m; i++) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (uint k; k < mem.length; k++) {
}
address[] memory mem2;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < mem2.length; i++) {
}
uint n2 = mem2.length;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < n2; i++) {
}
uint m2;
m2 = mem2.length;
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (i = 0; i < m2; i++) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 4b7do5
for (k = 0; k < mem2.length; k++) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS 12cf32
for (uint j = stor.length; j > 0; j--) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS f6f853
for (k = 0; k < stor.length; k++) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS v5j3d9
for (i = mem.length; i > 0; i--) {
}
// <yes> <report> SOLIDITY_GAS_LIMIT_IN_LOOPS v5j3d9
for (j = mem2.length; j > 0; j--) {
}
}
}
```
### Abstract Syntax Tree
[Click Here](https://astexplorer.net/#/gist/48d86c63521f85c514f9bb027b3a03f7/d30bac03e87f5ae246c611966f23bc3f7dcae9e9) to view the AST for the above code. Code generated from AST Explorer using _solidity-parser-antlr-0.4.11_
### Code Result
```
SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 24
column: 8
content: for(uinti=0;i<_addr.length;i++){}
ruleId: SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 39
column: 8
content: for(uintk;k<_addr.length;k++){}
ruleId: SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 55
column: 8
content: for(uinti=0;i<mem.length;i++){}
ruleId: SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 70
column: 8
content: for(uintk;k<mem.length;k++){}
ruleId: SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 76
column: 8
content: for(i=0;i<mem2.length;i++){}
ruleId: SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 91
column: 8
content: for(k=0;k<mem2.length;k++){}
ruleId: SOLIDITY_EXTRA_GAS_IN_LOOPS
patternId: d3j11j
severity: 1
line: 99
column: 8
content: for(k=0;k<stor.length;k++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 24
column: 8
content: for(uinti=0;i<_addr.length;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 29
column: 8
content: for(i=0;i<n;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 35
column: 8
content: for(i=0;i<m;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 39
column: 8
content: for(uintk;k<_addr.length;k++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 55
column: 8
content: for(uinti=0;i<mem.length;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 60
column: 8
content: for(i=0;i<n;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 66
column: 8
content: for(i=0;i<m;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 70
column: 8
content: for(uintk;k<mem.length;k++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 76
column: 8
content: for(i=0;i<mem2.length;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 81
column: 8
content: for(i=0;i<n2;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 87
column: 8
content: for(i=0;i<m2;i++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 91
column: 8
content: for(k=0;k<mem2.length;k++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: f6f853
severity: 2
line: 99
column: 8
content: for(k=0;k<stor.length;k++){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 12cf32
severity: 2
line: 43
column: 8
content: for(i=_addr.length;i>0;i--){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 12cf32
severity: 2
line: 46
column: 8
content: for(uintj=_addr.length;j>0;j--){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 12cf32
severity: 2
line: 95
column: 8
content: for(uintj=stor.length;j>0;j--){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 12cf32
severity: 2
line: 103
column: 8
content: for(i=mem.length;i>0;i--){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 12cf32
severity: 2
line: 107
column: 8
content: for(j=mem2.length;j>0;j--){}
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 17f23a
severity: 1
line: 17
column: 15
content: y[5]<x
ruleId: SOLIDITY_GAS_LIMIT_IN_LOOPS
patternId: 38f6c7
severity: 2
line: 12
column: 8
content: while(x<foo()){}
ruleId: SOLIDITY_UPGRADE_TO_050
patternId: 341gim
severity: 1
line: 21
column: 21
content: address[]_addr
ruleId: SOLIDITY_VISIBILITY
patternId: 910067
severity: 1
line: 52
column: 4
content: functiontestForMemory(address[]memorymem){for(uinti=0;i<mem.length;i++){}uintn=mem.length;for(i=0;i<n;i++){}uintm;m=mem.length;for(i=0;i<m;i++){}for(uintk;k<mem.length;k++){}address[]memorymem2;for(i=0;i<mem2.length;i++){}uintn2=mem2.length;for(i=0;i<n2;i++){}uintm2;m2=mem2.length;for(i=0;i<m2;i++){}for(k=0;k<mem2.length;k++){}for(uintj=stor.length;j>0;j--){}for(k=0;k<stor.length;k++){}for(i=mem.length;i>0;i--){}for(j=mem2.length;j>0;j--){}}
ruleId: SOLIDITY_VISIBILITY
patternId: b51ce0
severity: 1
line: 50
column: 4
content: address[]stor;
SOLIDITY_VISIBILITY :2
SOLIDITY_EXTRA_GAS_IN_LOOPS :7
SOLIDITY_UPGRADE_TO_050 :1
SOLIDITY_GAS_LIMIT_IN_LOOPS :20
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment