From 700fe5a07a010276bfc8e5508fd9fc62913c857b Mon Sep 17 00:00:00 2001 From: Aleksandr Sobolev Date: Wed, 18 Dec 2019 13:20:53 +0600 Subject: [PATCH] Update website content (#224) * Add details to requirement_simple bytecode locations * Tweak location info for SWC-128 * misformatted bytecode offsets * Update README.md Updating links and some minor textual changes. * Slightly more descriptive error * Print full error * Clarify scope (#220) * Kaden zipfel feature/gas griefing (#222) * Insufficient gas griefing * Add newlines * Fix improper newlines * Make changes to relayer contracts * Add CWE reference * Fix link * Rename to SWC-126 * No target redeploy * Fix compiler warnings * Update SWC definition [ci skip] --- README.md | 17 +- entries/SWC-126.md | 19 + export/swc-definition.json | 9 + scripts/update_swc.js | 3 +- .../dos_address/dos_address.yaml | 2 +- .../dos_gas_limit/dos_number/dos_number.yaml | 5 +- .../dos_gas_limit/dos_simple/dos_simple.yaml | 5 +- .../relayer/relayer.json | 1239 ++++++++++++++ .../relayer/relayer.sol | 36 + .../relayer/relayer.yaml | 8 + .../relayer_fixed/relayer_fixed.json | 1473 +++++++++++++++++ .../relayer_fixed/relayer_fixed.sol | 36 + .../relayer_fixed/relayer_fixed.yaml | 5 + .../requirement_simple.yaml | 5 +- 14 files changed, 2847 insertions(+), 15 deletions(-) create mode 100644 entries/SWC-126.md create mode 100644 test_cases/solidity/insufficient_gas_griefing/relayer/relayer.json create mode 100644 test_cases/solidity/insufficient_gas_griefing/relayer/relayer.sol create mode 100644 test_cases/solidity/insufficient_gas_griefing/relayer/relayer.yaml create mode 100644 test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.json create mode 100644 test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.sol create mode 100644 test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.yaml diff --git a/README.md b/README.md index 4d8175b2..0d8e6b8c 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ [![Discord](https://img.shields.io/discord/481002907366588416.svg)](https://discord.gg/qcNvR2r) -The Smart Contract Weakness Classification Registry is an implementation of the weakness classification scheme proposed in [EIP-1470](https://github.com/ethereum/EIPs/issues/1469). It is loosely aligned to the terminologies and structure used in the Common Weakness Enumeration ([CWE](https://cwe.mitre.org)) while overlaying a wide range of weakness variants that are specific to smart contracts. +The Smart Contract Weakness Classification Registry (SWC Registry) is an implementation of the weakness classification scheme proposed in [EIP-1470](https://github.com/ethereum/EIPs/issues/1469). It is loosely aligned to the terminologies and structure used in the Common Weakness Enumeration ([CWE](https://cwe.mitre.org)) while overlaying a wide range of weakness variants that are specific to smart contracts. The goals of this project are as follows: -- Provide a straight forward way to classify security issues in smart contract systems. +- Provide a straightforward way to classify security issues in smart contract systems. - Define a common language for describing security issues in smart contract systems' architecture, design, or code. - Serve as a way to train and increase performance for smart contract security analysis tools. @@ -35,7 +35,7 @@ Link to external references that contain useful additional information on the is ``` -## Create a new Test Case +## Create a new test case Test cases should be as varied as possible and include both simple test cases and real-world samples of vulnerable smart contracts. The test cases are grouped into subdirectories based on a single weakness variant or based on more complex real world contract systems that can contain various weakness variants. A single test case consists of the following structure: @@ -89,7 +89,7 @@ The configuration contains meta-information about the weaknesses contained in a Before you create a PR for the first time make sure you have read: -- the sections [Create a new SWC entry](#create-a-new-swc-entry) and [Create a test case](#create-a-new-test-case). +- the sections [Create a new SWC entry](#create-a-new-swc-entry) and [Create a new test case](#create-a-new-test-case). - read several existing SWC definitions and their test cases. From time to time there will be challenges on [Gitcoin](https://gitcoin.co). Follow the below link to check what challenges are currently open. @@ -98,8 +98,13 @@ From time to time there will be challenges on [Gitcoin](https://gitcoin.co). Fol -## Contact +### Scope of Weaknesses + +SWCs should be concerned with weaknesses that can be identified within the code of a smart contract, typically Solidity. +Weaknesses in 'smart contract adjacent' code should not be included. For example, the [gas siphoning attack](https://github.com/SmartContractSecurity/SWC-registry/pull/140) occurs in wallet code, and should be protected against in wallet code. -This repository is maintained by the [Mythril](https://mythril.ai) team. Join the #swc-registry channel on the [Mythril Community Discord Server](https://discord.gg/qcNvR2r) for discussions. +## Contact +This repository is maintained by the team behind [MythX](https://mythx.io). +Please join the #swc-registry channel on the [MythX Discord](https://discord.gg/qcNvR2r) for discussions. diff --git a/entries/SWC-126.md b/entries/SWC-126.md new file mode 100644 index 00000000..42b5f7e9 --- /dev/null +++ b/entries/SWC-126.md @@ -0,0 +1,19 @@ +# Title +Insufficient Gas Griefing + +## Relationships +[CWE-691: Insufficient Control Flow Management](https://cwe.mitre.org/data/definitions/691.html) + +## Description +Insufficient gas griefing attacks can be performed on contracts which accept data and use it in a sub-call on another contract. If the sub-call fails, either the whole transaction is reverted, or execution is continued. In the case of a relayer contract, the user who executes the transaction, the 'forwarder', can effectively censor transactions by using just enough gas to execute the transaction, but not enough for the sub-call to succeed. + +## Remediation +There are two options to prevent insufficient gas griefing: + +- Only allow trusted users to relay transactions. +- Require that the forwarder provides enough gas. + +## References +- [Consensys Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/known_attacks/#insufficient-gas-griefing) +- [What does griefing mean?](https://ethereum.stackexchange.com/questions/62829/what-does-griefing-mean) +- [Griefing Attacks: Are they profitable for the attacker?](https://ethereum.stackexchange.com/questions/73261/griefing-attacks-are-they-profitable-for-the-attacker) \ No newline at end of file diff --git a/export/swc-definition.json b/export/swc-definition.json index 975b6b56..57f957a8 100644 --- a/export/swc-definition.json +++ b/export/swc-definition.json @@ -233,6 +233,15 @@ "Remediation": "When inheriting multiple contracts, especially if they have identical functions, a developer should carefully specify inheritance in the correct order. The rule of thumb is to inherit contracts from more /general/ to more /specific/." } }, + "SWC-126": { + "markdown": "# Title\nInsufficient Gas Griefing\n\n## Relationships\n[CWE-691: Insufficient Control Flow Management](https://cwe.mitre.org/data/definitions/691.html)\n\n## Description\nInsufficient gas griefing attacks can be performed on contracts which accept data and use it in a sub-call on another contract. If the sub-call fails, either the whole transaction is reverted, or execution is continued. In the case of a relayer contract, the user who executes the transaction, the 'forwarder', can effectively censor transactions by using just enough gas to execute the transaction, but not enough for the sub-call to succeed.\n\n## Remediation\nThere are two options to prevent insufficient gas griefing:\n\n- Only allow trusted users to relay transactions.\n- Require that the forwarder provides enough gas.\n\n## References\n- [Consensys Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/known_attacks/#insufficient-gas-griefing)\n- [What does griefing mean?](https://ethereum.stackexchange.com/questions/62829/what-does-griefing-mean)\n- [Griefing Attacks: Are they profitable for the attacker?](https://ethereum.stackexchange.com/questions/73261/griefing-attacks-are-they-profitable-for-the-attacker)", + "content": { + "Title": "Insufficient Gas Griefing", + "Relationships": "[CWE-691: Insufficient Control Flow Management](https://cwe.mitre.org/data/definitions/691.html)", + "Description": "Insufficient gas griefing attacks can be performed on contracts which accept data and use it in a sub-call on another contract. If the sub-call fails, either the whole transaction is reverted, or execution is continued. In the case of a relayer contract, the user who executes the transaction, the 'forwarder', can effectively censor transactions by using just enough gas to execute the transaction, but not enough for the sub-call to succeed.", + "Remediation": "There are two options to prevent insufficient gas griefing:\n\n\n- Only allow trusted users to relay transactions.\n- Require that the forwarder provides enough gas." + } + }, "SWC-127": { "markdown": "# Title \nArbitrary Jump with Function Type Variable\n\n## Relationships\n[CWE-695: Use of Low-Level Functionality](https://cwe.mitre.org/data/definitions/695.html)\n\n## Description \nSolidity supports function types. That is, a variable of function type can be assigned with a reference to a function with a matching signature. The function saved to such variable can be called just like a regular function.\n\nThe problem arises when a user has the ability to arbitrarily change the function type variable and thus execute random code instructions. As Solidity doesn't support pointer arithmetics, it's impossible to change such variable to an arbitrary value. However, if the developer uses assembly instructions, such as `mstore` or assign operator, in the worst case scenario an attacker is able to point a function type variable to any code instruction, violating required validations and required state changes.\n\n## Remediation\nThe use of assembly should be minimal. A developer should not allow a user to assign arbitrary values to function type variables.\n\n## References \n* [Solidity CTF](https://medium.com/authio/solidity-ctf-part-2-safe-execution-ad6ded20e042)\n* [Solidity docs - Solidity Assembly](https://solidity.readthedocs.io/en/v0.4.25/assembly.html)\n* [Solidity docs - Function Types](https://solidity.readthedocs.io/en/v0.4.25/types.html#function-types)\n", "content": { diff --git a/scripts/update_swc.js b/scripts/update_swc.js index e7673f41..674c193c 100644 --- a/scripts/update_swc.js +++ b/scripts/update_swc.js @@ -36,7 +36,8 @@ const generateSWC = () => { }, }; } catch(e) { - console.log(`[ERROR] Wrong document format: ${name}.md`) + console.log(`[ERROR] Wrong document format: ${name}.md, provide content for all required headings`) + console.log(e) if (command && command === 'markdown-validate') { process.exit(1); } diff --git a/test_cases/solidity/dos_gas_limit/dos_address/dos_address.yaml b/test_cases/solidity/dos_gas_limit/dos_address/dos_address.yaml index bdfc9aee..f0f22ef8 100644 --- a/test_cases/solidity/dos_gas_limit/dos_address/dos_address.yaml +++ b/test_cases/solidity/dos_gas_limit/dos_address/dos_address.yaml @@ -6,4 +6,4 @@ issues: - bytecode_offsets: '0x53aef779087c1829c3990fbf300aaafe4ccbd3328e8b6a630c7484b8c921aa8e': [408] line_numbers: - dos_address.sol: [9,10,11,12] + dos_address.sol: [10] diff --git a/test_cases/solidity/dos_gas_limit/dos_number/dos_number.yaml b/test_cases/solidity/dos_gas_limit/dos_number/dos_number.yaml index 0fd838b9..fb0885cc 100644 --- a/test_cases/solidity/dos_gas_limit/dos_number/dos_number.yaml +++ b/test_cases/solidity/dos_gas_limit/dos_number/dos_number.yaml @@ -3,7 +3,6 @@ issues: - id: SWC-128 count: 1 locations: - - bytecode_offsets: - '0x3e71712b10e2878a71d36b38b239d8560bedb5a1e0e9b6ade8d61ce8ec28fdf1': [413] + - bytecode_offsets: {} line_numbers: - dos_number.sol: [11,12,13,14,15,16] + dos_number.sol: [29] diff --git a/test_cases/solidity/dos_gas_limit/dos_simple/dos_simple.yaml b/test_cases/solidity/dos_gas_limit/dos_simple/dos_simple.yaml index bfab7787..7f5549b2 100644 --- a/test_cases/solidity/dos_gas_limit/dos_simple/dos_simple.yaml +++ b/test_cases/solidity/dos_gas_limit/dos_simple/dos_simple.yaml @@ -3,7 +3,6 @@ issues: - id: SWC-128 count: 1 locations: - - bytecode_offsets: - '0x81cafe753b96f7315b17b2bb5184b64b8f2cfe66a7077e94569355ce4dfa5208': [150] + - bytecode_offsets: {} line_numbers: - dos_simple.sol: [10,11,12] + dos_simple.sol: [16] diff --git a/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.json b/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.json new file mode 100644 index 00000000..cb9bce26 --- /dev/null +++ b/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.json @@ -0,0 +1,1239 @@ +{ + "contracts": + { + "relayer.sol:Relayer": + { + "bin": "608060405234801561001057600080fd5b506105ed806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80638f0d6f1714610030575b600080fd5b6100e96004803603602081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100eb565b005b60001515600160008054815260200190815260200160002060010160009054906101000a900460ff16151514610189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f73616d65207472616e73616374696f6e2074776963650000000000000000000081525060200191505060405180910390fd5b80600160008054815260200190815260200160002060000190805190602001906101b49291906103cc565b5060018060008054815260200190815260200160002060010160006101000a81548160ff0219169083151502179055506001600080828254019250508190555060006040516102029061044c565b604051809103906000f08015801561021e573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff16826040516024018080602001828103825283818151815260200191508051906020019080838360005b8381101561027c578082015181840152602081019050610261565b50505050905090810190601f1680156102a95780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040527f09c5eabe000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061035e578051825260208201915060208101905060208303925061033b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103c0576040519150601f19603f3d011682016040523d82523d6000602084013e6103c5565b606091505b5050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061040d57805160ff191683800117855561043b565b8280016001018555821561043b579182015b8281111561043a57825182559160200191906001019061041f565b5b5090506104489190610459565b5090565b61013a8061047f83390190565b61047b91905b8082111561047757600081600090555060010161045f565b5090565b9056fe608060405234801561001057600080fd5b5061011a806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806309c5eabe14602d575b600080fd5b60e060048036036020811015604157600080fd5b8101908080359060200190640100000000811115605d57600080fd5b820183602082011115606e57600080fd5b80359060200191846001830284011164010000000083111715608f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505060e2565b005b5056fea265627a7a723158203a266030aa9aafb92be95625f535a09e3f319efb620eca69e1eda429e93a463b64736f6c634300050e0032a265627a7a72315820f7199e5e4e4a23395e6f17dad1fb21973ffa497e6d73a91a57794d7af164ca8964736f6c634300050e0032", + "bin-runtime": "608060405234801561001057600080fd5b506004361061002b5760003560e01c80638f0d6f1714610030575b600080fd5b6100e96004803603602081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100eb565b005b60001515600160008054815260200190815260200160002060010160009054906101000a900460ff16151514610189576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f73616d65207472616e73616374696f6e2074776963650000000000000000000081525060200191505060405180910390fd5b80600160008054815260200190815260200160002060000190805190602001906101b49291906103cc565b5060018060008054815260200190815260200160002060010160006101000a81548160ff0219169083151502179055506001600080828254019250508190555060006040516102029061044c565b604051809103906000f08015801561021e573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff16826040516024018080602001828103825283818151815260200191508051906020019080838360005b8381101561027c578082015181840152602081019050610261565b50505050905090810190601f1680156102a95780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040527f09c5eabe000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061035e578051825260208201915060208101905060208303925061033b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103c0576040519150601f19603f3d011682016040523d82523d6000602084013e6103c5565b606091505b5050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061040d57805160ff191683800117855561043b565b8280016001018555821561043b579182015b8281111561043a57825182559160200191906001019061041f565b5b5090506104489190610459565b5090565b61013a8061047f83390190565b61047b91905b8082111561047757600081600090555060010161045f565b5090565b9056fe608060405234801561001057600080fd5b5061011a806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806309c5eabe14602d575b600080fd5b60e060048036036020811015604157600080fd5b8101908080359060200190640100000000811115605d57600080fd5b820183602082011115606e57600080fd5b80359060200191846001830284011164010000000083111715608f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505060e2565b005b5056fea265627a7a723158203a266030aa9aafb92be95625f535a09e3f319efb620eca69e1eda429e93a463b64736f6c634300050e0032a265627a7a72315820f7199e5e4e4a23395e6f17dad1fb21973ffa497e6d73a91a57794d7af164ca8964736f6c634300050e0032", + "srcmap": "212:634:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;212:634:0;;;;;;;", + "srcmap-runtime": "212:634:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;212:634:0;;;;;;;;;;;;;;;;;;;376:467;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;376:467:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;376:467:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;376:467:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;376:467:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;376:467:0;;;;;;;;;;;;;;;:::i;:::-;;;547:5;507:45;;:12;:27;520:13;;507:27;;;;;;;;;;;:36;;;;;;;;;;;;:45;;;499:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;625:5;590:12;:27;603:13;;590:27;;;;;;;;;;;:32;;:40;;;;;;;;;;;;:::i;:::-;;680:4;641:12;:27;654:13;;641:27;;;;;;;;;;;:36;;;:43;;;;;;;;;;;;;;;;;;712:1;695:13;;:18;;;;;;;;;;;726:13;742:12;;;;;:::i;:::-;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;742:12:0;726:28;;773:6;765:20;;828:5;786:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;786:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;786:48:0;;;;;;;38:4:-1;29:7;25:18;67:10;61:17;96:58;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;786:48:0;765:70;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;765:70:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;765:70:0;;376:467;;:::o;212:634::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o" + }, + "relayer.sol:Target": + { + "bin": "608060405234801561001057600080fd5b5061011a806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806309c5eabe14602d575b600080fd5b60e060048036036020811015604157600080fd5b8101908080359060200190640100000000811115605d57600080fd5b820183602082011115606e57600080fd5b80359060200191846001830284011164010000000083111715608f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505060e2565b005b5056fea265627a7a723158203a266030aa9aafb92be95625f535a09e3f319efb620eca69e1eda429e93a463b64736f6c634300050e0032", + "bin-runtime": "6080604052348015600f57600080fd5b506004361060285760003560e01c806309c5eabe14602d575b600080fd5b60e060048036036020811015604157600080fd5b8101908080359060200190640100000000811115605d57600080fd5b820183602082011115606e57600080fd5b80359060200191846001830284011164010000000083111715608f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505060e2565b005b5056fea265627a7a723158203a266030aa9aafb92be95625f535a09e3f319efb620eca69e1eda429e93a463b64736f6c634300050e0032", + "srcmap": "881:112:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;881:112:0;;;;;;;", + "srcmap-runtime": "881:112:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;881:112:0;;;;;;;;;;;;;;;;;;;904:86;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;904:86:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;904:86:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;904:86:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;904:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;904:86:0;;;;;;;;;;;;;;;:::i;:::-;;;;:::o" + } + }, + "sourceList": + [ + "relayer.sol" + ], + "sources": + { + "relayer.sol": + { + "AST": + { + "attributes": + { + "absolutePath": "relayer.sol", + "exportedSymbols": + { + "Relayer": + [ + 64 + ], + "Target": + [ + 71 + ] + } + }, + "children": + [ + { + "attributes": + { + "literals": + [ + "solidity", + "^", + "0.5", + ".0" + ] + }, + "id": 1, + "name": "PragmaDirective", + "src": "185:23:0" + }, + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + 71 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 64 + ], + "name": "Relayer", + "scope": 72 + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "transactionId", + "scope": 64, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 2, + "name": "ElementaryTypeName", + "src": "236:4:0" + } + ], + "id": 3, + "name": "VariableDeclaration", + "src": "236:18:0" + }, + { + "attributes": + { + "canonicalName": "Relayer.Tx", + "name": "Tx", + "scope": 64, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "data", + "scope": 8, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bytes", + "type": "bytes" + }, + "id": 4, + "name": "ElementaryTypeName", + "src": "284:5:0" + } + ], + "id": 5, + "name": "VariableDeclaration", + "src": "284:10:0" + }, + { + "attributes": + { + "constant": false, + "name": "executed", + "scope": 8, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bool", + "type": "bool" + }, + "id": 6, + "name": "ElementaryTypeName", + "src": "305:4:0" + } + ], + "id": 7, + "name": "VariableDeclaration", + "src": "305:13:0" + } + ], + "id": 8, + "name": "StructDefinition", + "src": "263:63:0" + }, + { + "attributes": + { + "constant": false, + "name": "transactions", + "scope": 64, + "stateVariable": true, + "storageLocation": "default", + "type": "mapping(uint256 => struct Relayer.Tx)", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "type": "mapping(uint256 => struct Relayer.Tx)" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 9, + "name": "ElementaryTypeName", + "src": "343:4:0" + }, + { + "attributes": + { + "contractScope": null, + "name": "Tx", + "referencedDeclaration": 8, + "type": "struct Relayer.Tx" + }, + "id": 10, + "name": "UserDefinedTypeName", + "src": "351:2:0" + } + ], + "id": 11, + "name": "Mapping", + "src": "334:20:0" + } + ], + "id": 12, + "name": "VariableDeclaration", + "src": "334:33:0" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "relay", + "scope": 64, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "_data", + "scope": 63, + "stateVariable": false, + "storageLocation": "memory", + "type": "bytes", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bytes", + "type": "bytes" + }, + "id": 13, + "name": "ElementaryTypeName", + "src": "391:5:0" + } + ], + "id": 14, + "name": "VariableDeclaration", + "src": "391:18:0" + } + ], + "id": 15, + "name": "ParameterList", + "src": "390:20:0" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 16, + "name": "ParameterList", + "src": "418:0:0" + }, + { + "children": + [ + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "tuple()", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6be6c6f69f65505e931166cd869202e87f1094f5a415f99447236b294d9fd9e9", + "typeString": "literal_string \"same transaction twice\"" + } + ], + "overloadedDeclarations": + [ + 89, + 90 + ], + "referencedDeclaration": 90, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 17, + "name": "Identifier", + "src": "499:7:0" + }, + { + "attributes": + { + "argumentTypes": null, + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "executed", + "referencedDeclaration": 7, + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Relayer.Tx storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 12, + "type": "mapping(uint256 => struct Relayer.Tx storage ref)", + "value": "transactions" + }, + "id": 18, + "name": "Identifier", + "src": "507:12:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 19, + "name": "Identifier", + "src": "520:13:0" + } + ], + "id": 20, + "name": "IndexAccess", + "src": "507:27:0" + } + ], + "id": 21, + "name": "MemberAccess", + "src": "507:36:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "66616c7365", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "bool", + "type": "bool", + "value": "false" + }, + "id": 22, + "name": "Literal", + "src": "547:5:0" + } + ], + "id": 23, + "name": "BinaryOperation", + "src": "507:45:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "73616d65207472616e73616374696f6e207477696365", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "string", + "type": "literal_string \"same transaction twice\"", + "value": "same transaction twice" + }, + "id": 24, + "name": "Literal", + "src": "554:24:0" + } + ], + "id": 25, + "name": "FunctionCall", + "src": "499:80:0" + } + ], + "id": 26, + "name": "ExpressionStatement", + "src": "499:80:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bytes storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "data", + "referencedDeclaration": 5, + "type": "bytes storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Relayer.Tx storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 12, + "type": "mapping(uint256 => struct Relayer.Tx storage ref)", + "value": "transactions" + }, + "id": 27, + "name": "Identifier", + "src": "590:12:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 28, + "name": "Identifier", + "src": "603:13:0" + } + ], + "id": 29, + "name": "IndexAccess", + "src": "590:27:0" + } + ], + "id": 30, + "name": "MemberAccess", + "src": "590:32:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 14, + "type": "bytes memory", + "value": "_data" + }, + "id": 31, + "name": "Identifier", + "src": "625:5:0" + } + ], + "id": 32, + "name": "Assignment", + "src": "590:40:0" + } + ], + "id": 33, + "name": "ExpressionStatement", + "src": "590:40:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "executed", + "referencedDeclaration": 7, + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Relayer.Tx storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 12, + "type": "mapping(uint256 => struct Relayer.Tx storage ref)", + "value": "transactions" + }, + "id": 34, + "name": "Identifier", + "src": "641:12:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 35, + "name": "Identifier", + "src": "654:13:0" + } + ], + "id": 36, + "name": "IndexAccess", + "src": "641:27:0" + } + ], + "id": 37, + "name": "MemberAccess", + "src": "641:36:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "74727565", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "bool", + "type": "bool", + "value": "true" + }, + "id": 38, + "name": "Literal", + "src": "680:4:0" + } + ], + "id": 39, + "name": "Assignment", + "src": "641:43:0" + } + ], + "id": 40, + "name": "ExpressionStatement", + "src": "641:43:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "+=", + "type": "uint256" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 41, + "name": "Identifier", + "src": "695:13:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 42, + "name": "Literal", + "src": "712:1:0" + } + ], + "id": 43, + "name": "Assignment", + "src": "695:18:0" + } + ], + "id": 44, + "name": "ExpressionStatement", + "src": "695:18:0" + }, + { + "attributes": + { + "assignments": + [ + 46 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "target", + "scope": 62, + "stateVariable": false, + "storageLocation": "default", + "type": "contract Target", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "Target", + "referencedDeclaration": 71, + "type": "contract Target" + }, + "id": 45, + "name": "UserDefinedTypeName", + "src": "726:6:0" + } + ], + "id": 46, + "name": "VariableDeclaration", + "src": "726:13:0" + }, + { + "attributes": + { + "argumentTypes": null, + "arguments": + [ + null + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "contract Target", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + null + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "type": "function () returns (contract Target)" + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "Target", + "referencedDeclaration": 71, + "type": "contract Target" + }, + "id": 47, + "name": "UserDefinedTypeName", + "src": "746:6:0" + } + ], + "id": 48, + "name": "NewExpression", + "src": "742:10:0" + } + ], + "id": 49, + "name": "FunctionCall", + "src": "742:12:0" + } + ], + "id": 50, + "name": "VariableDeclarationStatement", + "src": "726:28:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "tuple(bool,bytes memory)", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "call", + "referencedDeclaration": null, + "type": "function (bytes memory) payable returns (bool,bytes memory)" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "address", + "type_conversion": true + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_Target_$71", + "typeString": "contract Target" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(address)", + "value": "address" + }, + "id": 51, + "name": "ElementaryTypeNameExpression", + "src": "765:7:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 46, + "type": "contract Target", + "value": "target" + }, + "id": 52, + "name": "Identifier", + "src": "773:6:0" + } + ], + "id": 53, + "name": "FunctionCall", + "src": "765:15:0" + } + ], + "id": 54, + "name": "MemberAccess", + "src": "765:20:0" + }, + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "bytes memory", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_stringliteral_09c5eabe8d7d17edb2a5ee22b8241b3c45db7f41e72a7ae433139a0e48dc3584", + "typeString": "literal_string \"execute(bytes)\"" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "member_name": "encodeWithSignature", + "referencedDeclaration": null, + "type": "function (string memory) pure returns (bytes memory)" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 73, + "type": "abi", + "value": "abi" + }, + "id": 55, + "name": "Identifier", + "src": "786:3:0" + } + ], + "id": 56, + "name": "MemberAccess", + "src": "786:23:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "6578656375746528627974657329", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "string", + "type": "literal_string \"execute(bytes)\"", + "value": "execute(bytes)" + }, + "id": 57, + "name": "Literal", + "src": "810:16:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 14, + "type": "bytes memory", + "value": "_data" + }, + "id": 58, + "name": "Identifier", + "src": "828:5:0" + } + ], + "id": 59, + "name": "FunctionCall", + "src": "786:48:0" + } + ], + "id": 60, + "name": "FunctionCall", + "src": "765:70:0" + } + ], + "id": 61, + "name": "ExpressionStatement", + "src": "765:70:0" + } + ], + "id": 62, + "name": "Block", + "src": "418:425:0" + } + ], + "id": 63, + "name": "FunctionDefinition", + "src": "376:467:0" + } + ], + "id": 64, + "name": "ContractDefinition", + "src": "212:634:0" + }, + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 71 + ], + "name": "Target", + "scope": 72 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "execute", + "scope": 71, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "_data", + "scope": 70, + "stateVariable": false, + "storageLocation": "memory", + "type": "bytes", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bytes", + "type": "bytes" + }, + "id": 65, + "name": "ElementaryTypeName", + "src": "921:5:0" + } + ], + "id": 66, + "name": "VariableDeclaration", + "src": "921:18:0" + } + ], + "id": 67, + "name": "ParameterList", + "src": "920:20:0" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 68, + "name": "ParameterList", + "src": "948:0:0" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 69, + "name": "Block", + "src": "948:42:0" + } + ], + "id": 70, + "name": "FunctionDefinition", + "src": "904:86:0" + } + ], + "id": 71, + "name": "ContractDefinition", + "src": "881:112:0" + } + ], + "id": 72, + "name": "SourceUnit", + "src": "185:810:0" + } + } + }, + "version": "0.5.14+commit.01f1aaa4.Windows.msvc" +} diff --git a/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.sol b/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.sol new file mode 100644 index 00000000..7d32b904 --- /dev/null +++ b/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.sol @@ -0,0 +1,36 @@ +/* + * @source: https://consensys.github.io/smart-contract-best-practices/known_attacks/#insufficient-gas-griefing + * @author: ConsenSys Diligence + * Modified by Kaden Zipfel + */ + +pragma solidity ^0.5.0; + +contract Relayer { + uint transactionId; + + struct Tx { + bytes data; + bool executed; + } + + mapping (uint => Tx) transactions; + + function relay(Target target, bytes memory _data) public returns(bool) { + // replay protection; do not call the same transaction twice + require(transactions[transactionId].executed == false, 'same transaction twice'); + transactions[transactionId].data = _data; + transactions[transactionId].executed = true; + transactionId += 1; + + (bool success, ) = address(target).call(abi.encodeWithSignature("execute(bytes)", _data)); + return success; + } +} + +// Contract called by Relayer +contract Target { + function execute(bytes memory _data) public { + // Execute contract code + } +} diff --git a/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.yaml b/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.yaml new file mode 100644 index 00000000..7aae07ab --- /dev/null +++ b/test_cases/solidity/insufficient_gas_griefing/relayer/relayer.yaml @@ -0,0 +1,8 @@ +description: Relayer contract without protection against insufficient gas griefing +issues: +- id: SWC-126 + count: 1 + locations: + - bytecode_offsets: {} + line_numbers: + relayer.sol: [27] diff --git a/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.json b/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.json new file mode 100644 index 00000000..3ed9cbeb --- /dev/null +++ b/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.json @@ -0,0 +1,1473 @@ +{ + "contracts": + { + "relayer_fixed.sol:Relayer": + { + "bin": "608060405234801561001057600080fd5b5061068a806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80635c9e3d6d14610030575b600080fd5b6100f36004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506100f5565b005b60001515600160008054815260200190815260200160002060010160009054906101000a900460ff16151514610193576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f73616d65207472616e73616374696f6e2074776963650000000000000000000081525060200191505060405180910390fd5b81600160008054815260200190815260200160002060000190805190602001906101be9291906103df565b5060018060008054815260200190815260200160002060010160006101000a81548160ff02191690831515021790555060016000808282540192505081905550600060405161020c9061045f565b604051809103906000f080158015610228573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1683836040516024018080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561028d578082015181840152602081019050610272565b50505050905090810190601f1680156102ba5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f09c5eabe000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610370578051825260208201915060208101905060208303925061034d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103d2576040519150601f19603f3d011682016040523d82523d6000602084013e6103d7565b606091505b505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061042057805160ff191683800117855561044e565b8280016001018555821561044e579182015b8281111561044d578251825591602001919060010190610432565b5b50905061045b919061046c565b5090565b6101c48061049283390190565b61048e91905b8082111561048a576000816000905550600101610472565b5090565b9056fe608060405234801561001057600080fd5b506101a4806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ab5898e814610030575b600080fd5b6100f36004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506100f5565b005b805a101561016b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f6e6f7420656e6f7567682067617300000000000000000000000000000000000081525060200191505060405180910390fd5b505056fea265627a7a72315820ef7c0ad827a081a053c38af1227183fc3a77c440307817b4edf404bf36a741aa64736f6c634300050e0032a265627a7a72315820ba1c12f74477d94435387415d518194b22c3930813ab9dbbdf5e301f7f324cc564736f6c634300050e0032", + "bin-runtime": "608060405234801561001057600080fd5b506004361061002b5760003560e01c80635c9e3d6d14610030575b600080fd5b6100f36004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506100f5565b005b60001515600160008054815260200190815260200160002060010160009054906101000a900460ff16151514610193576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f73616d65207472616e73616374696f6e2074776963650000000000000000000081525060200191505060405180910390fd5b81600160008054815260200190815260200160002060000190805190602001906101be9291906103df565b5060018060008054815260200190815260200160002060010160006101000a81548160ff02191690831515021790555060016000808282540192505081905550600060405161020c9061045f565b604051809103906000f080158015610228573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1683836040516024018080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561028d578082015181840152602081019050610272565b50505050905090810190601f1680156102ba5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f09c5eabe000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610370578051825260208201915060208101905060208303925061034d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103d2576040519150601f19603f3d011682016040523d82523d6000602084013e6103d7565b606091505b505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061042057805160ff191683800117855561044e565b8280016001018555821561044e579182015b8281111561044d578251825591602001919060010190610432565b5b50905061045b919061046c565b5090565b6101c48061049283390190565b61048e91905b8082111561048a576000816000905550600101610472565b5090565b9056fe608060405234801561001057600080fd5b506101a4806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ab5898e814610030575b600080fd5b6100f36004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506100f5565b005b805a101561016b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f6e6f7420656e6f7567682067617300000000000000000000000000000000000081525060200191505060405180910390fd5b505056fea265627a7a72315820ef7c0ad827a081a053c38af1227183fc3a77c440307817b4edf404bf36a741aa64736f6c634300050e0032a265627a7a72315820ba1c12f74477d94435387415d518194b22c3930813ab9dbbdf5e301f7f324cc564736f6c634300050e0032", + "srcmap": "212:661:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;212:661:0;;;;;;;", + "srcmap-runtime": "212:661:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;212:661:0;;;;;;;;;;;;;;;;;;;376:494;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;376:494:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;376:494:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;376:494:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;376:494:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;376:494:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;563:5;523:45;;:12;:27;536:13;;523:27;;;;;;;;;;;:36;;;;;;;;;;;;:45;;;515:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;641:5;606:12;:27;619:13;;606:27;;;;;;;;;;;:32;;:40;;;;;;;;;;;;:::i;:::-;;696:4;657:12;:27;670:13;;657:27;;;;;;;;;;;:36;;;:43;;;;;;;;;;;;;;;;;;728:1;711:13;;:18;;;;;;;;;;;742:13;758:12;;;;;:::i;:::-;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;758:12:0;742:28;;789:6;781:20;;844:5;851:9;802:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;802:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;802:59:0;;;;;;;38:4:-1;29:7;25:18;67:10;61:17;96:58;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;802:59:0;781:81;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;781:81:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;781:81:0;;376:494;;;:::o;212:661::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o" + }, + "relayer_fixed.sol:Target": + { + "bin": "608060405234801561001057600080fd5b506101a4806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ab5898e814610030575b600080fd5b6100f36004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506100f5565b005b805a101561016b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f6e6f7420656e6f7567682067617300000000000000000000000000000000000081525060200191505060405180910390fd5b505056fea265627a7a72315820ef7c0ad827a081a053c38af1227183fc3a77c440307817b4edf404bf36a741aa64736f6c634300050e0032", + "bin-runtime": "608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ab5898e814610030575b600080fd5b6100f36004803603604081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001909291905050506100f5565b005b805a101561016b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f6e6f7420656e6f7567682067617300000000000000000000000000000000000081525060200191505060405180910390fd5b505056fea265627a7a72315820ef7c0ad827a081a053c38af1227183fc3a77c440307817b4edf404bf36a741aa64736f6c634300050e0032", + "srcmap": "908:188:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;908:188:0;;;;;;;", + "srcmap-runtime": "908:188:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;908:188:0;;;;;;;;;;;;;;;;;;;931:162;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;931:162:0;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;931:162:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;931:162:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;931:162:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;931:162:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;1023:9;1010;:22;;1002:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;931:162;;:::o" + } + }, + "sourceList": + [ + "relayer_fixed.sol" + ], + "sources": + { + "relayer_fixed.sol": + { + "AST": + { + "attributes": + { + "absolutePath": "relayer_fixed.sol", + "exportedSymbols": + { + "Relayer": + [ + 67 + ], + "Target": + [ + 84 + ] + } + }, + "children": + [ + { + "attributes": + { + "literals": + [ + "solidity", + "^", + "0.5", + ".0" + ] + }, + "id": 1, + "name": "PragmaDirective", + "src": "185:23:0" + }, + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + 84 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 67 + ], + "name": "Relayer", + "scope": 85 + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "transactionId", + "scope": 67, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 2, + "name": "ElementaryTypeName", + "src": "236:4:0" + } + ], + "id": 3, + "name": "VariableDeclaration", + "src": "236:18:0" + }, + { + "attributes": + { + "canonicalName": "Relayer.Tx", + "name": "Tx", + "scope": 67, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "data", + "scope": 8, + "stateVariable": false, + "storageLocation": "default", + "type": "bytes", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bytes", + "type": "bytes" + }, + "id": 4, + "name": "ElementaryTypeName", + "src": "284:5:0" + } + ], + "id": 5, + "name": "VariableDeclaration", + "src": "284:10:0" + }, + { + "attributes": + { + "constant": false, + "name": "executed", + "scope": 8, + "stateVariable": false, + "storageLocation": "default", + "type": "bool", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bool", + "type": "bool" + }, + "id": 6, + "name": "ElementaryTypeName", + "src": "305:4:0" + } + ], + "id": 7, + "name": "VariableDeclaration", + "src": "305:13:0" + } + ], + "id": 8, + "name": "StructDefinition", + "src": "263:63:0" + }, + { + "attributes": + { + "constant": false, + "name": "transactions", + "scope": 67, + "stateVariable": true, + "storageLocation": "default", + "type": "mapping(uint256 => struct Relayer.Tx)", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "type": "mapping(uint256 => struct Relayer.Tx)" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 9, + "name": "ElementaryTypeName", + "src": "343:4:0" + }, + { + "attributes": + { + "contractScope": null, + "name": "Tx", + "referencedDeclaration": 8, + "type": "struct Relayer.Tx" + }, + "id": 10, + "name": "UserDefinedTypeName", + "src": "351:2:0" + } + ], + "id": 11, + "name": "Mapping", + "src": "334:20:0" + } + ], + "id": 12, + "name": "VariableDeclaration", + "src": "334:33:0" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "relay", + "scope": 67, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "_data", + "scope": 66, + "stateVariable": false, + "storageLocation": "memory", + "type": "bytes", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bytes", + "type": "bytes" + }, + "id": 13, + "name": "ElementaryTypeName", + "src": "391:5:0" + } + ], + "id": 14, + "name": "VariableDeclaration", + "src": "391:18:0" + }, + { + "attributes": + { + "constant": false, + "name": "_gasLimit", + "scope": 66, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 15, + "name": "ElementaryTypeName", + "src": "411:4:0" + } + ], + "id": 16, + "name": "VariableDeclaration", + "src": "411:14:0" + } + ], + "id": 17, + "name": "ParameterList", + "src": "390:36:0" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 18, + "name": "ParameterList", + "src": "434:0:0" + }, + { + "children": + [ + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "tuple()", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6be6c6f69f65505e931166cd869202e87f1094f5a415f99447236b294d9fd9e9", + "typeString": "literal_string \"same transaction twice\"" + } + ], + "overloadedDeclarations": + [ + 102, + 103 + ], + "referencedDeclaration": 103, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 19, + "name": "Identifier", + "src": "515:7:0" + }, + { + "attributes": + { + "argumentTypes": null, + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "==", + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "member_name": "executed", + "referencedDeclaration": 7, + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Relayer.Tx storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 12, + "type": "mapping(uint256 => struct Relayer.Tx storage ref)", + "value": "transactions" + }, + "id": 20, + "name": "Identifier", + "src": "523:12:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 21, + "name": "Identifier", + "src": "536:13:0" + } + ], + "id": 22, + "name": "IndexAccess", + "src": "523:27:0" + } + ], + "id": 23, + "name": "MemberAccess", + "src": "523:36:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "66616c7365", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "bool", + "type": "bool", + "value": "false" + }, + "id": 24, + "name": "Literal", + "src": "563:5:0" + } + ], + "id": 25, + "name": "BinaryOperation", + "src": "523:45:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "73616d65207472616e73616374696f6e207477696365", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "string", + "type": "literal_string \"same transaction twice\"", + "value": "same transaction twice" + }, + "id": 26, + "name": "Literal", + "src": "570:24:0" + } + ], + "id": 27, + "name": "FunctionCall", + "src": "515:80:0" + } + ], + "id": 28, + "name": "ExpressionStatement", + "src": "515:80:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bytes storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "data", + "referencedDeclaration": 5, + "type": "bytes storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Relayer.Tx storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 12, + "type": "mapping(uint256 => struct Relayer.Tx storage ref)", + "value": "transactions" + }, + "id": 29, + "name": "Identifier", + "src": "606:12:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 30, + "name": "Identifier", + "src": "619:13:0" + } + ], + "id": 31, + "name": "IndexAccess", + "src": "606:27:0" + } + ], + "id": 32, + "name": "MemberAccess", + "src": "606:32:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 14, + "type": "bytes memory", + "value": "_data" + }, + "id": 33, + "name": "Identifier", + "src": "641:5:0" + } + ], + "id": 34, + "name": "Assignment", + "src": "606:40:0" + } + ], + "id": 35, + "name": "ExpressionStatement", + "src": "606:40:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "member_name": "executed", + "referencedDeclaration": 7, + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "struct Relayer.Tx storage ref" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 12, + "type": "mapping(uint256 => struct Relayer.Tx storage ref)", + "value": "transactions" + }, + "id": 36, + "name": "Identifier", + "src": "657:12:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 37, + "name": "Identifier", + "src": "670:13:0" + } + ], + "id": 38, + "name": "IndexAccess", + "src": "657:27:0" + } + ], + "id": 39, + "name": "MemberAccess", + "src": "657:36:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "74727565", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "bool", + "type": "bool", + "value": "true" + }, + "id": 40, + "name": "Literal", + "src": "696:4:0" + } + ], + "id": 41, + "name": "Assignment", + "src": "657:43:0" + } + ], + "id": 42, + "name": "ExpressionStatement", + "src": "657:43:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "+=", + "type": "uint256" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256", + "value": "transactionId" + }, + "id": 43, + "name": "Identifier", + "src": "711:13:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 44, + "name": "Literal", + "src": "728:1:0" + } + ], + "id": 45, + "name": "Assignment", + "src": "711:18:0" + } + ], + "id": 46, + "name": "ExpressionStatement", + "src": "711:18:0" + }, + { + "attributes": + { + "assignments": + [ + 48 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "target", + "scope": 65, + "stateVariable": false, + "storageLocation": "default", + "type": "contract Target", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "Target", + "referencedDeclaration": 84, + "type": "contract Target" + }, + "id": 47, + "name": "UserDefinedTypeName", + "src": "742:6:0" + } + ], + "id": 48, + "name": "VariableDeclaration", + "src": "742:13:0" + }, + { + "attributes": + { + "argumentTypes": null, + "arguments": + [ + null + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "contract Target", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + null + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "type": "function () returns (contract Target)" + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "Target", + "referencedDeclaration": 84, + "type": "contract Target" + }, + "id": 49, + "name": "UserDefinedTypeName", + "src": "762:6:0" + } + ], + "id": 50, + "name": "NewExpression", + "src": "758:10:0" + } + ], + "id": 51, + "name": "FunctionCall", + "src": "758:12:0" + } + ], + "id": 52, + "name": "VariableDeclarationStatement", + "src": "742:28:0" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "tuple(bool,bytes memory)", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "member_name": "call", + "referencedDeclaration": null, + "type": "function (bytes memory) payable returns (bool,bytes memory)" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "address", + "type_conversion": true + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_Target_$84", + "typeString": "contract Target" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(address)", + "value": "address" + }, + "id": 53, + "name": "ElementaryTypeNameExpression", + "src": "781:7:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 48, + "type": "contract Target", + "value": "target" + }, + "id": 54, + "name": "Identifier", + "src": "789:6:0" + } + ], + "id": 55, + "name": "FunctionCall", + "src": "781:15:0" + } + ], + "id": 56, + "name": "MemberAccess", + "src": "781:20:0" + }, + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "bytes memory", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_stringliteral_09c5eabe8d7d17edb2a5ee22b8241b3c45db7f41e72a7ae433139a0e48dc3584", + "typeString": "literal_string \"execute(bytes)\"" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "member_name": "encodeWithSignature", + "referencedDeclaration": null, + "type": "function (string memory) pure returns (bytes memory)" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 86, + "type": "abi", + "value": "abi" + }, + "id": 57, + "name": "Identifier", + "src": "802:3:0" + } + ], + "id": 58, + "name": "MemberAccess", + "src": "802:23:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "6578656375746528627974657329", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "string", + "type": "literal_string \"execute(bytes)\"", + "value": "execute(bytes)" + }, + "id": 59, + "name": "Literal", + "src": "826:16:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 14, + "type": "bytes memory", + "value": "_data" + }, + "id": 60, + "name": "Identifier", + "src": "844:5:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 16, + "type": "uint256", + "value": "_gasLimit" + }, + "id": 61, + "name": "Identifier", + "src": "851:9:0" + } + ], + "id": 62, + "name": "FunctionCall", + "src": "802:59:0" + } + ], + "id": 63, + "name": "FunctionCall", + "src": "781:81:0" + } + ], + "id": 64, + "name": "ExpressionStatement", + "src": "781:81:0" + } + ], + "id": 65, + "name": "Block", + "src": "434:436:0" + } + ], + "id": 66, + "name": "FunctionDefinition", + "src": "376:494:0" + } + ], + "id": 67, + "name": "ContractDefinition", + "src": "212:661:0" + }, + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 84 + ], + "name": "Target", + "scope": 85 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "execute", + "scope": 84, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "_data", + "scope": 83, + "stateVariable": false, + "storageLocation": "memory", + "type": "bytes", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "bytes", + "type": "bytes" + }, + "id": 68, + "name": "ElementaryTypeName", + "src": "948:5:0" + } + ], + "id": 69, + "name": "VariableDeclaration", + "src": "948:18:0" + }, + { + "attributes": + { + "constant": false, + "name": "_gasLimit", + "scope": 83, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 70, + "name": "ElementaryTypeName", + "src": "968:4:0" + } + ], + "id": 71, + "name": "VariableDeclaration", + "src": "968:14:0" + } + ], + "id": 72, + "name": "ParameterList", + "src": "947:36:0" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 73, + "name": "ParameterList", + "src": "991:0:0" + }, + { + "children": + [ + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "tuple()", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_62b7fac48775b941984d2c094301f344b889700ca0ceaf4bf42b6389c547b477", + "typeString": "literal_string \"not enough gas\"" + } + ], + "overloadedDeclarations": + [ + 102, + 103 + ], + "referencedDeclaration": 103, + "type": "function (bool,string memory) pure", + "value": "require" + }, + "id": 74, + "name": "Identifier", + "src": "1002:7:0" + }, + { + "attributes": + { + "argumentTypes": null, + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": ">=", + "type": "bool" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "arguments": + [ + null + ], + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "type": "uint256", + "type_conversion": false + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + null + ], + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 92, + "type": "function () view returns (uint256)", + "value": "gasleft" + }, + "id": 75, + "name": "Identifier", + "src": "1010:7:0" + } + ], + "id": 76, + "name": "FunctionCall", + "src": "1010:9:0" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 71, + "type": "uint256", + "value": "_gasLimit" + }, + "id": 77, + "name": "Identifier", + "src": "1023:9:0" + } + ], + "id": 78, + "name": "BinaryOperation", + "src": "1010:22:0" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "6e6f7420656e6f75676820676173", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "string", + "type": "literal_string \"not enough gas\"", + "value": "not enough gas" + }, + "id": 79, + "name": "Literal", + "src": "1034:16:0" + } + ], + "id": 80, + "name": "FunctionCall", + "src": "1002:49:0" + } + ], + "id": 81, + "name": "ExpressionStatement", + "src": "1002:49:0" + } + ], + "id": 82, + "name": "Block", + "src": "991:102:0" + } + ], + "id": 83, + "name": "FunctionDefinition", + "src": "931:162:0" + } + ], + "id": 84, + "name": "ContractDefinition", + "src": "908:188:0" + } + ], + "id": 85, + "name": "SourceUnit", + "src": "185:913:0" + } + } + }, + "version": "0.5.14+commit.01f1aaa4.Windows.msvc" +} diff --git a/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.sol b/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.sol new file mode 100644 index 00000000..8c68f12c --- /dev/null +++ b/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.sol @@ -0,0 +1,36 @@ +/* + * @source: https://consensys.github.io/smart-contract-best-practices/known_attacks/#insufficient-gas-griefing + * @author: ConsenSys Diligence + * Modified by Kaden Zipfel + */ + +pragma solidity ^0.5.0; + +contract Relayer { + uint transactionId; + + struct Tx { + bytes data; + bool executed; + } + + mapping (uint => Tx) transactions; + + function relay(Target target, bytes memory _data, uint _gasLimit) public { + // replay protection; do not call the same transaction twice + require(transactions[transactionId].executed == false, 'same transaction twice'); + transactions[transactionId].data = _data; + transactions[transactionId].executed = true; + transactionId += 1; + + address(target).call(abi.encodeWithSignature("execute(bytes)", _data, _gasLimit)); + } +} + +// Contract called by Relayer +contract Target { + function execute(bytes memory _data, uint _gasLimit) public { + require(gasleft() >= _gasLimit, 'not enough gas'); + // Execute contract code + } +} diff --git a/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.yaml b/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.yaml new file mode 100644 index 00000000..29333e60 --- /dev/null +++ b/test_cases/solidity/insufficient_gas_griefing/relayer_fixed/relayer_fixed.yaml @@ -0,0 +1,5 @@ +description: Relayer contract with protection against insufficient gas griefing +issues: +- id: SWC-126 + count: 0 + locations: [] diff --git a/test_cases/solidity/requirement_violations/requirement_simple/requirement_simple.yaml b/test_cases/solidity/requirement_violations/requirement_simple/requirement_simple.yaml index 6e048887..865b0c3b 100644 --- a/test_cases/solidity/requirement_violations/requirement_simple/requirement_simple.yaml +++ b/test_cases/solidity/requirement_violations/requirement_simple/requirement_simple.yaml @@ -4,6 +4,9 @@ issues: count: 1 locations: - bytecode_offsets: - '0xba541cbb2ac6dda7664b6ebdc6372297425c2eeabd88e0af5ca6310f9cf7bbd2': [263, 145] + '0xba541cbb2ac6dda7664b6ebdc6372297425c2eeabd88e0af5ca6310f9cf7bbd2': + - 263 + '0x2dbd524f734f1b06b19cbefbbb5e84bbc6203a04bc930c26141c40bb8ecf467b': + - 145 line_numbers: requirement_simple.sol: [6, 12]