diff --git a/crates/pyrometer/tests/no_killed_ctxs.rs b/crates/pyrometer/tests/no_killed_ctxs.rs index b9beb7d4..352d3896 100644 --- a/crates/pyrometer/tests/no_killed_ctxs.rs +++ b/crates/pyrometer/tests/no_killed_ctxs.rs @@ -238,3 +238,21 @@ fn test_variable() { let sol = include_str!("./test_data/variable.sol"); assert_no_ctx_killed(path_str, sol); } + +#[test] +#[should_panic] +fn test_broken() { + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let path_str = format!("{manifest_dir}/tests/test_data/broken.sol"); + let sol = include_str!("./test_data/broken.sol"); + assert_no_ctx_killed(path_str, sol); +} + +#[test] +#[should_panic] +fn test_todo() { + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let path_str = format!("{manifest_dir}/tests/test_data/todo.sol"); + let sol = include_str!("./test_data/todo.sol"); + assert_no_ctx_killed(path_str, sol); +} diff --git a/crates/pyrometer/tests/test_data/assign.sol b/crates/pyrometer/tests/test_data/assign.sol index 64ce63cb..ebfd5f84 100644 --- a/crates/pyrometer/tests/test_data/assign.sol +++ b/crates/pyrometer/tests/test_data/assign.sol @@ -1,7 +1,6 @@ pragma solidity ^0.8.0; contract Assign { - function doAssignment() public { // Multi-value LHS (tuple) (uint x, uint y) = (uint16(1), 2); @@ -10,11 +9,5 @@ contract Assign { uint z = 3; (x, y) = (z, z); - - // uint[2] memory a = [uint(1), uint(2)]; - // uint[2] memory b = [uint(3), uint(4)]; - - - // (a, b) = (b, a); } -} \ No newline at end of file +} diff --git a/crates/pyrometer/tests/test_data/bin_op.sol b/crates/pyrometer/tests/test_data/bin_op.sol index 90db5cdb..c78d64d3 100644 --- a/crates/pyrometer/tests/test_data/bin_op.sol +++ b/crates/pyrometer/tests/test_data/bin_op.sol @@ -1,10 +1,9 @@ pragma solidity ^0.8.0; contract BinOp { - function testBinOp(int y) public { int x = 1; int z = 5 + x; int a = x * y; } -} \ No newline at end of file +} diff --git a/crates/pyrometer/tests/test_data/broken.sol b/crates/pyrometer/tests/test_data/broken.sol new file mode 100644 index 00000000..d32d9f55 --- /dev/null +++ b/crates/pyrometer/tests/test_data/broken.sol @@ -0,0 +1,270 @@ +pragma solidity ^0.8.0; + +/////// This block of code will live in variable.sol when fixed /////////// +contract B { + struct A { + address a; + } +} + +contract A is B { + A a; // contract A + + function return_struct() external returns (A memory) { + // a is of type B.A, *not* Contract::A + a = A(address(this)); + return a; + } +} + +////////////////////////////////////////////////////////////// + +///////// This whole contract will live in require_with_killed.sol when fixed /////////// +// Note: I've added broken@brock comments to the issues i know of +contract RequireWithKilled { + uint public count = 0; + uint storeRange = 0; + + function setStoreRange(uint x) public { + storeRange = x; + } + + function requireLt(uint x) public { + // set bounds for storeRange + require(5 < storeRange && storeRange < 100); + "pyro::variable::storeRange::range::[6, 99]"; // broken@brock this range appears as [0,99] + // set tighter bounds for x + require(6 < x && x < 99); + "pyro::variable::x::range::[7, 98]"; // broken@brock this range appears as [0,98] + // make x less than storeRange + require(x < storeRange); + } + + function requireLte(uint x) public { + // set bounds for storeRange + require(5 < storeRange && storeRange < 100); + // set tighter bounds for x + require(6 < x && x < 99); + // make x less than or equal to storeRange + require(x <= storeRange); + } + + function requireGt(uint x) public { + // set bounds for storeRange + require(5 < storeRange && storeRange < 100); + // set tighter bounds for x + require(6 < x && x < 99); + // make x greater than storeRange + require(x > storeRange); + } + + function requireGte(uint x) public { + // set bounds for storeRange + require(5 < storeRange && storeRange < 100); + // set tighter bounds for x + require(6 < x && x < 99); + // make x greater than or equal to storeRange + require(x >= storeRange); + } + + function requireEq(uint x) public { + // set bounds for storeRange + require(5 < storeRange && storeRange < 100); + // set tighter bounds for x + require(6 < x && x < 99); + // make x equal to storeRange + require(x == storeRange); + } + + function requireNeq(uint x) public { + // set bounds for storeRange + require(5 < storeRange && storeRange < 100); + // set tighter bounds for x + require(6 < x && x < 99); + // make x not equal to storeRange + require(x != storeRange); + } + + function setCount() public { + count = 0; + } + + function andShortCircuit() public { + count = 0; + // ( bump(false) && bump(true) ) || true , this will test that the second bump is not evaluated since the `and` short circuits + require( + (bumpCountIfValueEq1ThenReturn(1, false) && + bumpCountIfValueEq1ThenReturn(1, true)) || true + ); + "pyro::variable::count::range::[1, 1]"; // broken@brock `count` is not found in context. this goes for the other "pyro::" statements with `count` too + } + + function andFullCircuit() public { + count = 0; + // ( bump(true) && bump(true) ) , this will test that the second bump is evaluated since the `and` does not short circuit + // broken@brock `&&` has parse issues here + require( + (bumpCountIfValueEq1ThenReturn(1, true) && + bumpCountIfValueEq1ThenReturn(1, true)) + ); + "pyro::variable::count::range::[2, 2]"; + } + + function orShortCircuit() public { + count = 0; + // ( bump(true) || bump(true) ) , this will test that the second bump is not evaluated since the `or` short circuits + require( + bumpCountIfValueEq1ThenReturn(1, true) || + bumpCountIfValueEq1ThenReturn(1, true) + ); + "pyro::variable::count::range::[1, 1]"; + } + + function orShortCircuitRHS() public { + count = 0; + // ( bump(true) || bump(true) ) , this will test that the second bump is not evaluated since the `or` short circuits + require( + bumpCountIfValueEq1ThenReturn(2, true) || + bumpCountIfValueEq1ThenReturn(1, true) + ); + "pyro::variable::count::range::[0, 0]"; + + count = 0; + require(bumpCountIfValueEq1ThenReturn(1, true) || true); + "pyro::variable::count::range::[1, 1]"; + + count = 0; + require(true || bumpCountIfValueEq1ThenReturn(1, true)); + "pyro::variable::count::range::[0, 0]"; + } + + function yulAndFullCircuit() public { + count = 0; + assembly { + function bumpCountIfValueEq1ThenReturn(x, returnValue) -> result { + let count_val := sload(0) + // first if needs both x and count to be 0 + if and(eq(count_val, 0), eq(x, 0)) { + // add 1 to count + sstore(0, add(sload(0), 1)) + } + // second if needs both values to be 1 + if and(eq(count_val, 1), eq(x, 1)) { + // add 1 to count + sstore(0, add(sload(0), 1)) + } + result := true + } + + // in yul: rhs is evaluated, then lhs. no short circuiting + if or( + bumpCountIfValueEq1ThenReturn(1, true), + bumpCountIfValueEq1ThenReturn(0, true) + ) { + + } + } + "pyro::variable::count::range::[2, 2]"; + } + + function orFullCircuit() public { + count = 0; + // ( bump(false) || bump(true) ) , this will test that the second bump is evaluated since the `or` does not short circuit + require( + bumpCountIfValueEq1ThenReturn(1, false) || + bumpCountIfValueEq1ThenReturn(1, true) + ); + "pyro::variable::count::range::[2, 2]"; + } + + function bumpCountIfValueEq1ThenReturn( + uint8 x, + bool returnValue + ) internal returns (bool) { + if (x == 1) { + count += 1; + } + return returnValue; + } +} + +///////////////////////////////////////////////////////////////// + +////// This contract's functions will be merged into delete.sol when fixed /////////// +contract ComplexDelete { + struct ContactInfo { + string email; + string phone; + } + + struct Address { + string street; + string city; + string country; + uint256 postalCode; + } + + struct Employment { + string company; + string position; + uint256 startDate; + uint256 endDate; + } + + struct Education { + string institution; + string degree; + uint256 graduationYear; + } + + struct User { + uint256 id; + string name; + ContactInfo contactInfo; + Address[] addresses; + Employment[] employmentHistory; + Education[] educationHistory; + mapping(string => bool) preferences; + } + + mapping(uint256 => User) public users; + uint256[] public userIds; + + function deleteUserAddress(uint256 userId, uint256 addressIndex) public { + require( + addressIndex < users[userId].addresses.length, + "Address index out of bounds" + ); + users[userId].addresses[addressIndex] = users[userId].addresses[ + users[userId].addresses.length - 1 + ]; + users[userId].addresses.pop(); + } + + function deleteEmploymentHistory( + uint256 userId, + uint256 employmentIndex + ) public { + require( + employmentIndex < users[userId].employmentHistory.length, + "Employment index out of bounds" + ); + users[userId].employmentHistory[employmentIndex] = users[userId] + .employmentHistory[users[userId].employmentHistory.length - 1]; + users[userId].employmentHistory.pop(); + } + + function deleteEducationHistory( + uint256 userId, + uint256 educationIndex + ) public { + require( + educationIndex < users[userId].educationHistory.length, + "Education index out of bounds" + ); + users[userId].educationHistory[educationIndex] = users[userId] + .educationHistory[users[userId].educationHistory.length - 1]; + users[userId].educationHistory.pop(); + } +} +///////////////////////////////////////////////////////////////// diff --git a/crates/pyrometer/tests/test_data/cmp.sol b/crates/pyrometer/tests/test_data/cmp.sol index 2c7b0f32..5ca64b57 100644 --- a/crates/pyrometer/tests/test_data/cmp.sol +++ b/crates/pyrometer/tests/test_data/cmp.sol @@ -1,10 +1,8 @@ pragma solidity ^0.8.0; contract Cmp { - function testCmp(int x) public { uint a = 5; bool b = (5 < 6) || (5 == 6 && 0 < 1); // Correct the tuple comparison - } -} \ No newline at end of file +} diff --git a/crates/pyrometer/tests/test_data/delete.sol b/crates/pyrometer/tests/test_data/delete.sol index 1ab62cbb..23c3fc69 100644 --- a/crates/pyrometer/tests/test_data/delete.sol +++ b/crates/pyrometer/tests/test_data/delete.sol @@ -103,48 +103,10 @@ contract ComplexDelete { if (userIds[i] == userId) { userIds[i] = userIds[userIds.length - 1]; userIds.pop(); - // break; } } } - function deleteUserAddress(uint256 userId, uint256 addressIndex) public { - require( - addressIndex < users[userId].addresses.length, - "Address index out of bounds" - ); - users[userId].addresses[addressIndex] = users[userId].addresses[ - users[userId].addresses.length - 1 - ]; - users[userId].addresses.pop(); - } - - function deleteEmploymentHistory( - uint256 userId, - uint256 employmentIndex - ) public { - require( - employmentIndex < users[userId].employmentHistory.length, - "Employment index out of bounds" - ); - users[userId].employmentHistory[employmentIndex] = users[userId] - .employmentHistory[users[userId].employmentHistory.length - 1]; - users[userId].employmentHistory.pop(); - } - - function deleteEducationHistory( - uint256 userId, - uint256 educationIndex - ) public { - require( - educationIndex < users[userId].educationHistory.length, - "Education index out of bounds" - ); - users[userId].educationHistory[educationIndex] = users[userId] - .educationHistory[users[userId].educationHistory.length - 1]; - users[userId].educationHistory.pop(); - } - function deleteUserPreference(uint256 userId, string memory key) public { delete users[userId].preferences[key]; } @@ -170,68 +132,79 @@ contract ComplexDelete { } } -// contract UseComplexDelete { -// ComplexDelete t; +contract UseComplexDelete { + ComplexDelete t; -// constructor() { -// t = new ComplexDelete(); -// } - -// function useIt() public { -// // Add users -// t.addUser(1, "Alice", "alice@example.com", "1234567890"); -// t.addUser(2, "Bob", "bob@example.com", "0987654321"); + constructor() { + t = new ComplexDelete(); + } -// // Add addresses -// t.addUserAddress(1, "123 Main St", "New York", "USA", 10001); -// t.addUserAddress(1, "456 Elm St", "Los Angeles", "USA", 90001); -// t.addUserAddress(2, "789 Oak St", "Chicago", "USA", 60601); + function useIt() public { + // Add users + t.addUser(1, "Alice", "alice@example.com", "1234567890"); + t.addUser(2, "Bob", "bob@example.com", "0987654321"); -// // Add employment history -// t.addEmploymentHistory(1, "TechCorp", "Developer", 1609459200, 1640995200); -// t.addEmploymentHistory(1, "WebSoft", "Senior Developer", 1641081600, 0); -// t.addEmploymentHistory(2, "DataFirm", "Analyst", 1577836800, 0); + // Add addresses + t.addUserAddress(1, "123 Main St", "New York", "USA", 10001); + t.addUserAddress(1, "456 Elm St", "Los Angeles", "USA", 90001); + t.addUserAddress(2, "789 Oak St", "Chicago", "USA", 60601); -// // Add education history -// t.addEducationHistory(1, "Tech University", "BSc Computer Science", 2020); -// t.addEducationHistory(2, "Data College", "MSc Data Science", 2019); + // Add employment history + t.addEmploymentHistory( + 1, + "TechCorp", + "Developer", + 1609459200, + 1640995200 + ); + t.addEmploymentHistory(1, "WebSoft", "Senior Developer", 1641081600, 0); + t.addEmploymentHistory(2, "DataFirm", "Analyst", 1577836800, 0); + + // Add education history + t.addEducationHistory( + 1, + "Tech University", + "BSc Computer Science", + 2020 + ); + t.addEducationHistory(2, "Data College", "MSc Data Science", 2019); -// // Set preferences -// t.setUserPreference(1, "receiveNewsletter", true); -// t.setUserPreference(1, "darkMode", false); -// t.setUserPreference(2, "receiveNewsletter", false); + // Set preferences + t.setUserPreference(1, "receiveNewsletter", true); + t.setUserPreference(1, "darkMode", false); + t.setUserPreference(2, "receiveNewsletter", false); -// // Test deletions and updates + // Test deletions and updates -// // Delete an address -// t.deleteUserAddress(1, 0); + // Delete an address + // t.deleteUserAddress(1, 0); // TODO @brock these need uncommented when the pop is fixed and these functions are back -// // Delete employment history -// t.deleteEmploymentHistory(1, 0); + // Delete employment history + // t.deleteEmploymentHistory(1, 0); // TODO @brock these need uncommented when the pop is fixed and these functions are back -// // Delete education history -// t.deleteEducationHistory(2, 0); + // Delete education history + // t.deleteEducationHistory(2, 0); // TODO @brock these need uncommented when the pop is fixed and these functions are back -// // Delete user preference -// t.deleteUserPreference(1, "darkMode"); + // Delete user preference + t.deleteUserPreference(1, "darkMode"); -// // Update contact info -// t.updateContactInfo(2, "bob.new@example.com", "1122334455"); + // Update contact info + t.updateContactInfo(2, "bob.new@example.com", "1122334455"); -// // Clear all addresses for a user -// t.clearAllUserAddresses(1); + // Clear all addresses for a user + t.clearAllUserAddresses(1); -// // Clear all employment history for a user -// t.clearAllEmploymentHistory(2); + // Clear all employment history for a user + t.clearAllEmploymentHistory(2); -// // Clear all education history for a user -// t.clearAllEducationHistory(1); + // Clear all education history for a user + t.clearAllEducationHistory(1); -// // Delete an entire user -// t.deleteUser(1); + // Delete an entire user + t.deleteUser(1); -// // Add a new user to test after deletions -// t.addUser(3, "Charlie", "charlie@example.com", "5556667777"); -// t.addUserAddress(3, "321 Pine St", "San Francisco", "USA", 94101); -// } -// } + // Add a new user to test after deletions + t.addUser(3, "Charlie", "charlie@example.com", "5556667777"); + t.addUserAddress(3, "321 Pine St", "San Francisco", "USA", 94101); + } +} diff --git a/crates/pyrometer/tests/test_data/dyn_types.sol b/crates/pyrometer/tests/test_data/dyn_types.sol index de1153ee..c4a6c6ff 100644 --- a/crates/pyrometer/tests/test_data/dyn_types.sol +++ b/crates/pyrometer/tests/test_data/dyn_types.sol @@ -111,7 +111,7 @@ contract DynTypes { function multiDimensionalArray() public returns (bool z) { uint256[][] memory multiArray = new uint256[][](2); uint256[] memory indices = new uint256[](2); - + indices[0] = 0; indices[1] = 1; @@ -124,5 +124,4 @@ contract DynTypes { z = true; } - } diff --git a/crates/pyrometer/tests/test_data/env.sol b/crates/pyrometer/tests/test_data/env.sol index afdb5b1f..c8b3065b 100644 --- a/crates/pyrometer/tests/test_data/env.sol +++ b/crates/pyrometer/tests/test_data/env.sol @@ -32,9 +32,7 @@ contract Env { tx.origin (address): sender of the transaction (full call chain) */ bytes32 a = blockhash(1); - bytes32 b = blobhash(1); uint c = block.basefee; - uint d = block.blobbasefee; uint e = block.chainid; address payable f = block.coinbase; uint g = block.difficulty; diff --git a/crates/pyrometer/tests/test_data/literals.sol b/crates/pyrometer/tests/test_data/literals.sol index cc138c36..7795e556 100644 --- a/crates/pyrometer/tests/test_data/literals.sol +++ b/crates/pyrometer/tests/test_data/literals.sol @@ -1,6 +1,5 @@ contract Literals { - - function foo() public returns (string memory) { + function foo() public returns (string memory) { uint a = 115792089237316195423570985008687907853269984665640564039457584007913129639935; // ok // uint b = 115792089237316195423570985008687907853269984665640564039457584007913129639936; // too big // uint c = 115792089237316195423570985008687907853269984665640564039457584007913129639935 ** 2; // too big @@ -9,6 +8,7 @@ contract Literals { uint f = 1.0 ** 2; // ok // uint g = 1.5 ** 2; // not uint uint h = 1.5 ** 0; // ok + h = 1.5 ** 0x0; // ok "pyro::variable::h::range::[1,1]"; uint256 i = 123 ** 10; // 792594609605189126649 address w = address(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF); @@ -32,8 +32,10 @@ contract Literals { "pyro::variable::k::range::[-84,-84]"; string memory s = unicode"🔥🔫"; // TODO unicode string values is not correct yet - bytes memory r = hex"11111111111111111111111111111111111111111111111111111111111111111111111111111111"; - r = hex"1111111111111111111111111111111111111111" hex"111111111111111111111111111111111111111111111111"; + bytes + memory r = hex"11111111111111111111111111111111111111111111111111111111111111111111111111111111"; + r = hex"1111111111111111111111111111111111111111" + hex"111111111111111111111111111111111111111111111111"; return s; } -} \ No newline at end of file +} diff --git a/crates/pyrometer/tests/test_data/require_with_killed.sol b/crates/pyrometer/tests/test_data/require_with_killed.sol index aaf06db7..e69de29b 100644 --- a/crates/pyrometer/tests/test_data/require_with_killed.sol +++ b/crates/pyrometer/tests/test_data/require_with_killed.sol @@ -1,164 +0,0 @@ -contract RequireWithKilled { - uint public count = 0; - uint storeRange = 0; - - function setStoreRange(uint x) public { - storeRange = x; - } - - // function requireLt(uint x) public { - // // set bounds for storeRange - // require(5 < storeRange && storeRange < 100); - // "pyro::variable::storeRange::range::[6, 99]"; - // // set tighter bounds for x - // require(6 < x && x < 99); - // "pyro::variable::x::range::[7, 98]"; - // // make x less than storeRange - // require(x < storeRange); - // } - - // function requireLte(uint x) public { - // // set bounds for storeRange - // require(5 < storeRange && storeRange < 100); - // // set tighter bounds for x - // require(6 < x && x < 99); - // // make x less than or equal to storeRange - // require(x <= storeRange); - // } - - // function requireGt(uint x) public { - // // set bounds for storeRange - // require(5 < storeRange && storeRange < 100); - // // set tighter bounds for x - // require(6 < x && x < 99); - // // make x greater than storeRange - // require(x > storeRange); - // } - - // function requireGte(uint x) public { - // // set bounds for storeRange - // require(5 < storeRange && storeRange < 100); - // // set tighter bounds for x - // require(6 < x && x < 99); - // // make x greater than or equal to storeRange - // require(x >= storeRange); - // } - - // function requireEq(uint x) public { - // // set bounds for storeRange - // require(5 < storeRange && storeRange < 100); - // // set tighter bounds for x - // require(6 < x && x < 99); - // // make x equal to storeRange - // require(x == storeRange); - // } - - // function requireNeq(uint x) public { - // // set bounds for storeRange - // require(5 < storeRange && storeRange < 100); - // // set tighter bounds for x - // require(6 < x && x < 99); - // // make x not equal to storeRange - // require(x != storeRange); - // } - - // function setCount() public { - // count = 0; - // } - // function andShortCircuit() public { - // count = 0; - // // ( bump(false) && bump(true) ) || true , this will test that the second bump is not evaluated since the `and` short circuits - // require( - // (bumpCountIfValueEq1ThenReturn(1, false) && - // bumpCountIfValueEq1ThenReturn(1, true)) || true - // ); - // "pyro::variable::count::range::[1, 1]"; - // } - - function andFullCircuit() public { - count = 0; - // ( bump(true) && bump(true) ) , this will test that the second bump is evaluated since the `and` does not short circuit - require( - (bumpCountIfValueEq1ThenReturn(1, true) && - bumpCountIfValueEq1ThenReturn(1, true)) - ); - "pyro::variable::count::range::[2, 2]"; - } - - // function orShortCircuit() public { - // count = 0; - // // ( bump(true) || bump(true) ) , this will test that the second bump is not evaluated since the `or` short circuits - // require( - // bumpCountIfValueEq1ThenReturn(1, true) || - // bumpCountIfValueEq1ThenReturn(1, true) - // ); - // "pyro::variable::count::range::[1, 1]"; - // } - - // function orShortCircuitRHS() public { - // count = 0; - // // ( bump(true) || bump(true) ) , this will test that the second bump is not evaluated since the `or` short circuits - // require( - // bumpCountIfValueEq1ThenReturn(2, true) || - // bumpCountIfValueEq1ThenReturn(1, true) - // ); - // "pyro::variable::count::range::[0, 0]"; - - // count = 0; - // require(bumpCountIfValueEq1ThenReturn(1, true) || true); - // "pyro::variable::count::range::[1, 1]"; - - // count = 0; - // require(true || bumpCountIfValueEq1ThenReturn(1, true)); - // "pyro::variable::count::range::[0, 0]"; - // } - - // function yulAndFullCircuit() public { - // count = 0; - // assembly { - // function bumpCountIfValueEq1ThenReturn(x, returnValue) -> result { - // let count_val := sload(0) - // // first if needs both x and count to be 0 - // if and(eq(count_val, 0), eq(x, 0)) { - // // add 1 to count - // sstore(0, add(sload(0), 1)) - // } - // // second if needs both values to be 1 - // if and(eq(count_val, 1), eq(x, 1)) { - // // add 1 to count - // sstore(0, add(sload(0), 1)) - // } - // result := true - // } - - // // in yul: rhs is evaluated, then lhs. no short circuiting - // if or( - // bumpCountIfValueEq1ThenReturn(1, true), - // bumpCountIfValueEq1ThenReturn(0, true) - // ) { - - // } - // } - // "pyro::variable::count::range::[2, 2]"; - // } - - // function orFullCircuit() public { - // count = 0; - // // ( bump(false) || bump(true) ) , this will test that the second bump is evaluated since the `or` does not short circuit - // require( - // bumpCountIfValueEq1ThenReturn(1, false) || - // bumpCountIfValueEq1ThenReturn(1, true) - // ); - // "pyro::variable::count::range::[2, 2]"; - // } - - function bumpCountIfValueEq1ThenReturn( - uint8 x, - bool returnValue - ) internal returns (bool) { - if (x == 1) { - count += 1; - } - return returnValue; - } -} diff --git a/crates/pyrometer/tests/test_data/todo.sol b/crates/pyrometer/tests/test_data/todo.sol new file mode 100644 index 00000000..8b5e3b29 --- /dev/null +++ b/crates/pyrometer/tests/test_data/todo.sol @@ -0,0 +1,44 @@ +pragma solidity ^0.8.0; + +contract Todo { + // will live in env.sol when added + function env() public view { + bytes32 b = blobhash(1); + uint d = block.blobbasefee; + } + + // will live in assign.sol when added + function array_literals() public pure { + uint[2] memory a = [uint(1), uint(2)]; + uint[2] memory b = [uint(3), uint(4)]; + } + + // will live in assign.sol when added + function array_slices( + uint[] calldata a + ) public pure returns (uint[] memory) { + require(a.length >= 4, "Array must have at least 4 elements"); + uint[] memory b = a[2:4]; + // if a is [1,2,3,4] + // then b is [3, 4] + return b; + } + + // this will live in loops.sol when fixed + function perform_break_literal() public pure { + for (uint256 i = 0; i < 10; i++) { + if (i == 5) { + break; // @brock this one weirdly does not error on the break + } + } + } + + // this will live in loops.sol when fixed + function perform_break(uint[] memory a) public pure { + for (uint256 i = 0; i < a.length; i++) { + if (i == a[i]) { + break; + } + } + } +} diff --git a/crates/pyrometer/tests/test_data/variable.sol b/crates/pyrometer/tests/test_data/variable.sol index 93ffed8b..c70dc46e 100644 --- a/crates/pyrometer/tests/test_data/variable.sol +++ b/crates/pyrometer/tests/test_data/variable.sol @@ -17,25 +17,9 @@ contract Variable { return a_user_type.aUserType; } - // function a_user_type_storage() public returns (uint) { - // aUserType storage a_user_type = a_user_type; - // return a_user_type.aUserType; - // } -} - -contract B { - struct A { - address a; - } -} - -contract A is B { - A a; // contract A - - function return_struct() external returns (A memory) { - // a is of type B.A, *not* Contract::A - a = A(address(this)); - return a; + function a_user_type_storage() public returns (uint) { + aUserType storage a_user_type = a_user_type; + return a_user_type.aUserType; } }