diff --git a/entries/SWC-Proposed.md b/entries/SWC-Proposed.md new file mode 100644 index 00000000..de586b6b --- /dev/null +++ b/entries/SWC-Proposed.md @@ -0,0 +1,18 @@ +# Title +Gas Siphon Attack + +## Relationships +[CWE-470: Use of Externally-Controlled Input to Select Classes or Code](https://cwe.mitre.org/data/definitions/470.html) + +## Description +When an account calls an address that belongs to a contract the contract's code will execute and the caller's account will pay the gas for this computation. Programs which send transactions, such as geth, estimate the gas needed automatically and will include the gas for that arbitrary computation. Therefore if the sender of a transaction auto generates the transaction without validation they may end up paying for gas used in unintended computation. Alone this is a form of griefing, but combined with a gas token structure it allows attackers to steal gas. +The current gas fee schedule includes a refund of gas when data stored in contracts or contracts themselves are deleted from the blockchain. This incentives keeping data stored on chain to a minimum. A gas token stores random data or creates contracts and then allows them to be deleted when called. This in effect creates a token which can be redeemed for gas in periods of high prices or network congestion. +If when an victim sends a transaction which allows arbitrary computation and the attacker uses that computation to mint gas token, then the attacker has in effect stolen gas from the victim. This has the largest effect on centralized exchanges, but could affect any contract which allows arbitrary code execution. +## Remediation +Parties which will send transactions should estimate or measure the gas cost of a transaction which contains no malicious code execution then limit all transactions to that amount. For example when directly sending ether the gas should be limited to 21000. +Applications should favor pull over push payments, transfers, and calls. They should avoid allowing contract calls to external code which they don't control. + +## References +* [Level K Medium Disclosure](https://medium.com/level-k/public-disclosure-malicious-gastoken-minting-236b2f8ace38) +* [Comprehensive Disclosure](https://drive.google.com/file/d/1mULop1LxHJJy_uzVBdc_xFItN9ck04Jj/view) +* [Gas Token Reference](https://gastoken.io/) diff --git a/test_cases/gas-siphon/gas_siphon_simple.json b/test_cases/gas-siphon/gas_siphon_simple.json new file mode 100644 index 00000000..5b217b20 --- /dev/null +++ b/test_cases/gas-siphon/gas_siphon_simple.json @@ -0,0 +1,1133 @@ +{ + "contracts" : + { + "gas_siphon_simple.sol:IdentityToken" : + { + "bin" : "608060405234801561001057600080fd5b506102ad806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a9059cbb14610046575b600080fd5b34801561005257600080fd5b50610091600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610093565b005b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156100e357600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff1663fc735e996040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101e157600080fd5b505af11580156101f5573d6000803e3d6000fd5b505050506040513d602081101561020b57600080fd5b81019080805190602001909291905050509050600060010281600019161415151561023557600080fd5b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081600019169055505050505600a165627a7a723058204eae55bbb6c9299cad3fd9a9c52c5538e942b7ae0094c2340db3db31492390e60029", + "bin-runtime" : "608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a9059cbb14610046575b600080fd5b34801561005257600080fd5b50610091600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610093565b005b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156100e357600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff1663fc735e996040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101e157600080fd5b505af11580156101f5573d6000803e3d6000fd5b505050506040513d602081101561020b57600080fd5b81019080805190602001909291905050509050600060010281600019161415151561023557600080fd5b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081600019169055505050505600a165627a7a723058204eae55bbb6c9299cad3fd9a9c52c5538e942b7ae0094c2340db3db31492390e60029", + "srcmap" : "100:615:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;100:615:0;;;;;;;", + "srcmap-runtime" : "100:615:0:-;;;;;;;;;;;;;;;;;;;;;;;;213:500;;8:9:-1;5:2;;;30:1;27;20:12;5:2;213:500:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;501:10;312:7;288:8;:20;297:10;288:20;;;;;;;;;;;;;;;;:31;;280:40;;;;;;;;395:7;378:8;:13;387:3;378:13;;;;;;;;;;;;;;;;:24;;;;;;;;;;;436:7;412:8;:20;421:10;412:20;;;;;;;;;;;;;;;;:31;;;;;;;;;;;524:3;514:21;;;:23;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;514:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;514:23:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;514:23:0;;;;;;;;;;;;;;;;501:36;;615:3;609:9;;:2;:9;;;;;601:18;;;;;;;;691:2;675:8;:13;684:3;675:13;;;;;;;;;;;;;;;:18;;;;;;;213:500;;;:::o" + }, + "gas_siphon_simple.sol:verifable" : + { + "bin" : "", + "bin-runtime" : "", + "srcmap" : "", + "srcmap-runtime" : "" + } + }, + "sourceList" : + [ + "gas_siphon_simple.sol" + ], + "sources" : + { + "gas_siphon_simple.sol" : + { + "AST" : + { + "attributes" : + { + "absolutePath" : "gas_siphon_simple.sol", + "exportedSymbols" : + { + "IdentityToken" : + [ + 60 + ], + "verifable" : + [ + 66 + ] + } + }, + "children" : + [ + { + "attributes" : + { + "literals" : + [ + "solidity", + "^", + "0.4", + ".25" + ] + }, + "id" : 1, + "name" : "PragmaDirective", + "src" : "0:24:0" + }, + { + "attributes" : + { + "baseContracts" : + [ + null + ], + "contractDependencies" : + [ + null + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 60 + ], + "name" : "IdentityToken", + "scope" : 67 + }, + "children" : + [ + { + "attributes" : + { + "constant" : false, + "name" : "identies", + "scope" : 60, + "stateVariable" : true, + "storageLocation" : "default", + "type" : "mapping(address => bytes32)", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "type" : "mapping(address => bytes32)" + }, + "children" : + [ + { + "attributes" : + { + "name" : "address", + "type" : "address" + }, + "id" : 2, + "name" : "ElementaryTypeName", + "src" : "136:7:0" + }, + { + "attributes" : + { + "name" : "bytes32", + "type" : "bytes32" + }, + "id" : 3, + "name" : "ElementaryTypeName", + "src" : "147:7:0" + } + ], + "id" : 4, + "name" : "Mapping", + "src" : "128:27:0" + } + ], + "id" : 5, + "name" : "VariableDeclaration", + "src" : "128:36:0" + }, + { + "attributes" : + { + "constant" : false, + "name" : "balances", + "scope" : 60, + "stateVariable" : true, + "storageLocation" : "default", + "type" : "mapping(address => uint256)", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "type" : "mapping(address => uint256)" + }, + "children" : + [ + { + "attributes" : + { + "name" : "address", + "type" : "address" + }, + "id" : 6, + "name" : "ElementaryTypeName", + "src" : "178:7:0" + }, + { + "attributes" : + { + "name" : "uint256", + "type" : "uint256" + }, + "id" : 7, + "name" : "ElementaryTypeName", + "src" : "189:7:0" + } + ], + "id" : 8, + "name" : "Mapping", + "src" : "170:27:0" + } + ], + "id" : 9, + "name" : "VariableDeclaration", + "src" : "170:36:0" + }, + { + "attributes" : + { + "constant" : false, + "documentation" : null, + "implemented" : true, + "isConstructor" : false, + "modifiers" : + [ + null + ], + "name" : "transfer", + "payable" : false, + "scope" : 60, + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "external" + }, + "children" : + [ + { + "children" : + [ + { + "attributes" : + { + "constant" : false, + "name" : "_to", + "scope" : 59, + "stateVariable" : false, + "storageLocation" : "default", + "type" : "address", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "name" : "address", + "type" : "address" + }, + "id" : 10, + "name" : "ElementaryTypeName", + "src" : "231:7:0" + } + ], + "id" : 11, + "name" : "VariableDeclaration", + "src" : "231:11:0" + }, + { + "attributes" : + { + "constant" : false, + "name" : "_amount", + "scope" : 59, + "stateVariable" : false, + "storageLocation" : "default", + "type" : "uint256", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "name" : "uint256", + "type" : "uint256" + }, + "id" : 12, + "name" : "ElementaryTypeName", + "src" : "244:7:0" + } + ], + "id" : 13, + "name" : "VariableDeclaration", + "src" : "244:15:0" + } + ], + "id" : 14, + "name" : "ParameterList", + "src" : "230:30:0" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 15, + "name" : "ParameterList", + "src" : "270: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" + } + ], + "overloadedDeclarations" : + [ + 84, + 85 + ], + "referencedDeclaration" : 84, + "type" : "function (bool) pure", + "value" : "require" + }, + "id" : 16, + "name" : "Identifier", + "src" : "280: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, + "isConstant" : false, + "isLValue" : true, + "isPure" : false, + "lValueRequested" : false, + "type" : "uint256" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 9, + "type" : "mapping(address => uint256)", + "value" : "balances" + }, + "id" : 17, + "name" : "Identifier", + "src" : "288:8:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "member_name" : "sender", + "referencedDeclaration" : null, + "type" : "address" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 81, + "type" : "msg", + "value" : "msg" + }, + "id" : 18, + "name" : "Identifier", + "src" : "297:3:0" + } + ], + "id" : 19, + "name" : "MemberAccess", + "src" : "297:10:0" + } + ], + "id" : 20, + "name" : "IndexAccess", + "src" : "288:20:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 13, + "type" : "uint256", + "value" : "_amount" + }, + "id" : 21, + "name" : "Identifier", + "src" : "312:7:0" + } + ], + "id" : 22, + "name" : "BinaryOperation", + "src" : "288:31:0" + } + ], + "id" : 23, + "name" : "FunctionCall", + "src" : "280:40:0" + } + ], + "id" : 24, + "name" : "ExpressionStatement", + "src" : "280:40:0" + }, + { + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "operator" : "+=", + "type" : "uint256" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : true, + "isPure" : false, + "lValueRequested" : true, + "type" : "uint256" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 9, + "type" : "mapping(address => uint256)", + "value" : "balances" + }, + "id" : 25, + "name" : "Identifier", + "src" : "378:8:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 11, + "type" : "address", + "value" : "_to" + }, + "id" : 26, + "name" : "Identifier", + "src" : "387:3:0" + } + ], + "id" : 27, + "name" : "IndexAccess", + "src" : "378:13:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 13, + "type" : "uint256", + "value" : "_amount" + }, + "id" : 28, + "name" : "Identifier", + "src" : "395:7:0" + } + ], + "id" : 29, + "name" : "Assignment", + "src" : "378:24:0" + } + ], + "id" : 30, + "name" : "ExpressionStatement", + "src" : "378:24:0" + }, + { + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "operator" : "-=", + "type" : "uint256" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : true, + "isPure" : false, + "lValueRequested" : true, + "type" : "uint256" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 9, + "type" : "mapping(address => uint256)", + "value" : "balances" + }, + "id" : 31, + "name" : "Identifier", + "src" : "412:8:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "member_name" : "sender", + "referencedDeclaration" : null, + "type" : "address" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 81, + "type" : "msg", + "value" : "msg" + }, + "id" : 32, + "name" : "Identifier", + "src" : "421:3:0" + } + ], + "id" : 33, + "name" : "MemberAccess", + "src" : "421:10:0" + } + ], + "id" : 34, + "name" : "IndexAccess", + "src" : "412:20:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 13, + "type" : "uint256", + "value" : "_amount" + }, + "id" : 35, + "name" : "Identifier", + "src" : "436:7:0" + } + ], + "id" : 36, + "name" : "Assignment", + "src" : "412:31:0" + } + ], + "id" : 37, + "name" : "ExpressionStatement", + "src" : "412:31:0" + }, + { + "attributes" : + { + "assignments" : + [ + 39 + ] + }, + "children" : + [ + { + "attributes" : + { + "constant" : false, + "name" : "id", + "scope" : 59, + "stateVariable" : false, + "storageLocation" : "default", + "type" : "bytes32", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "name" : "bytes32", + "type" : "bytes32" + }, + "id" : 38, + "name" : "ElementaryTypeName", + "src" : "501:7:0" + } + ], + "id" : 39, + "name" : "VariableDeclaration", + "src" : "501:10:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "arguments" : + [ + null + ], + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "isStructConstructorCall" : false, + "lValueRequested" : false, + "names" : + [ + null + ], + "type" : "bytes32", + "type_conversion" : false + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : + [ + null + ], + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "member_name" : "verify", + "referencedDeclaration" : 65, + "type" : "function () external returns (bytes32)" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "isStructConstructorCall" : false, + "lValueRequested" : false, + "names" : + [ + null + ], + "type" : "contract verifable", + "type_conversion" : true + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : + [ + { + "typeIdentifier" : "t_address", + "typeString" : "address" + } + ], + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 66, + "type" : "type(contract verifable)", + "value" : "verifable" + }, + "id" : 40, + "name" : "Identifier", + "src" : "514:9:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 11, + "type" : "address", + "value" : "_to" + }, + "id" : 41, + "name" : "Identifier", + "src" : "524:3:0" + } + ], + "id" : 42, + "name" : "FunctionCall", + "src" : "514:14:0" + } + ], + "id" : 43, + "name" : "MemberAccess", + "src" : "514:21:0" + } + ], + "id" : 44, + "name" : "FunctionCall", + "src" : "514:23:0" + } + ], + "id" : 45, + "name" : "VariableDeclarationStatement", + "src" : "501:36:0" + }, + { + "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" + } + ], + "overloadedDeclarations" : + [ + 84, + 85 + ], + "referencedDeclaration" : 84, + "type" : "function (bool) pure", + "value" : "require" + }, + "id" : 46, + "name" : "Identifier", + "src" : "601:7:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "commonType" : + { + "typeIdentifier" : "t_bytes32", + "typeString" : "bytes32" + }, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "operator" : "!=", + "type" : "bool" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 39, + "type" : "bytes32", + "value" : "id" + }, + "id" : 47, + "name" : "Identifier", + "src" : "609:2:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "hexvalue" : "307830", + "isConstant" : false, + "isLValue" : false, + "isPure" : true, + "lValueRequested" : false, + "subdenomination" : null, + "token" : "number", + "type" : "int_const 0", + "value" : "0x0" + }, + "id" : 48, + "name" : "Literal", + "src" : "615:3:0" + } + ], + "id" : 49, + "name" : "BinaryOperation", + "src" : "609:9:0" + } + ], + "id" : 50, + "name" : "FunctionCall", + "src" : "601:18:0" + } + ], + "id" : 51, + "name" : "ExpressionStatement", + "src" : "601:18:0" + }, + { + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : false, + "isPure" : false, + "lValueRequested" : false, + "operator" : "=", + "type" : "bytes32" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "isConstant" : false, + "isLValue" : true, + "isPure" : false, + "lValueRequested" : true, + "type" : "bytes32" + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 5, + "type" : "mapping(address => bytes32)", + "value" : "identies" + }, + "id" : 52, + "name" : "Identifier", + "src" : "675:8:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 11, + "type" : "address", + "value" : "_to" + }, + "id" : 53, + "name" : "Identifier", + "src" : "684:3:0" + } + ], + "id" : 54, + "name" : "IndexAccess", + "src" : "675:13:0" + }, + { + "attributes" : + { + "argumentTypes" : null, + "overloadedDeclarations" : + [ + null + ], + "referencedDeclaration" : 39, + "type" : "bytes32", + "value" : "id" + }, + "id" : 55, + "name" : "Identifier", + "src" : "691:2:0" + } + ], + "id" : 56, + "name" : "Assignment", + "src" : "675:18:0" + } + ], + "id" : 57, + "name" : "ExpressionStatement", + "src" : "675:18:0" + } + ], + "id" : 58, + "name" : "Block", + "src" : "270:443:0" + } + ], + "id" : 59, + "name" : "FunctionDefinition", + "src" : "213:500:0" + } + ], + "id" : 60, + "name" : "ContractDefinition", + "src" : "100:615:0" + }, + { + "attributes" : + { + "baseContracts" : + [ + null + ], + "contractDependencies" : + [ + null + ], + "contractKind" : "interface", + "documentation" : null, + "fullyImplemented" : false, + "linearizedBaseContracts" : + [ + 66 + ], + "name" : "verifable", + "scope" : 67 + }, + "children" : + [ + { + "attributes" : + { + "body" : null, + "constant" : false, + "documentation" : null, + "implemented" : false, + "isConstructor" : false, + "modifiers" : + [ + null + ], + "name" : "verify", + "payable" : false, + "scope" : 66, + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "external" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 61, + "name" : "ParameterList", + "src" : "757:2:0" + }, + { + "children" : + [ + { + "attributes" : + { + "constant" : false, + "name" : "", + "scope" : 65, + "stateVariable" : false, + "storageLocation" : "default", + "type" : "bytes32", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "name" : "bytes32", + "type" : "bytes32" + }, + "id" : 62, + "name" : "ElementaryTypeName", + "src" : "777:7:0" + } + ], + "id" : 63, + "name" : "VariableDeclaration", + "src" : "777:7:0" + } + ], + "id" : 64, + "name" : "ParameterList", + "src" : "776:9:0" + } + ], + "id" : 65, + "name" : "FunctionDefinition", + "src" : "742:44:0" + } + ], + "id" : 66, + "name" : "ContractDefinition", + "src" : "717:71:0" + } + ], + "id" : 67, + "name" : "SourceUnit", + "src" : "0:789:0" + } + } + }, + "version" : "0.4.25+commit.59dbf8f1.Linux.g++" +} diff --git a/test_cases/gas-siphon/gas_siphon_simple.sol b/test_cases/gas-siphon/gas_siphon_simple.sol new file mode 100644 index 00000000..83c55f51 --- /dev/null +++ b/test_cases/gas-siphon/gas_siphon_simple.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.4.25; + +//This tokens requires that all users be contract with identifiable users +contract IdentityToken{ + mapping(address => bytes32) identies; + mapping(address => uint256) balances; + + function transfer(address _to, uint256 _amount) external { + require(balances[msg.sender] >= _amount); //Make sure the caller can send _amount tokens + + balances[_to] += _amount; + balances[msg.sender] -= _amount; //Set balances before call to avoid reentrancy + + bytes32 id = verifable(_to).verify(); //Call contract to check if it has a compliant method + require(id != 0x0); //Require that the method has a meaningful id + identies[_to] = id; //Set the id + } +} + +interface verifable{ + function verify() external returns(bytes32); +} diff --git a/test_cases/gas-siphon/gas_siphon_simple.yaml b/test_cases/gas-siphon/gas_siphon_simple.yaml new file mode 100644 index 00000000..84e7617e --- /dev/null +++ b/test_cases/gas-siphon/gas_siphon_simple.yaml @@ -0,0 +1,7 @@ +description: "Gas Siphon Attack" +issues: +- id: "SWC-Proposed" + count: 1 + locations: + - line_numbers: [14] + - bytecode_offsets: []