dedicated safe integer truncation integration test (#435)

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
xermicus
2025-12-17 10:25:41 +01:00
committed by GitHub
parent 9446132608
commit 25ee4eef5a
3 changed files with 51 additions and 4 deletions
+4 -4
View File
@@ -20,7 +20,7 @@ pragma solidity ^0.8.28;
"dest": {
"Instantiated": 0
},
"data": "e2179b8e"
"data": "0be0e4a60000000000000000000000000000000000000000000000000000000000000000"
}
}
]
@@ -29,12 +29,12 @@ pragma solidity ^0.8.28;
contract MLoad {
constructor() payable {
assert(g() == 0);
assert(loadAt(0) == 0);
}
function g() public payable returns (uint m) {
function loadAt(uint _offset) public payable returns (uint m) {
assembly {
m := mload(0)
m := mload(_offset)
}
}
}
+9
View File
@@ -234,6 +234,15 @@ sol!(
);
case!("MCopy.sol", MCopy, memcpyCall, memcpy, payload: Bytes);
sol!(
contract MLoad {
constructor() payable;
function loadAt(uint _offset) public payable returns (uint m);
}
);
case!("MLoad.sol", MLoad, loadAtCall, load_at, _offset: U256);
sol!(
contract Call {
function value_transfer(address payable destination) public payable;
+38
View File
@@ -714,3 +714,41 @@ fn invalid_opcode_works() {
assert_eq!(result.weight_consumed, GAS_LIMIT);
}
/// Load from heap memory using an out of bounds offset and expect the
/// contract to hit the `invalid` syscall to use all gas (like on EVM).
///
/// The offset is picked such that a regular truncate would be in bounds.
#[test]
fn safe_truncate_int_to_xlen_works() {
let offset = 0x10000000_00000000u64;
let data = Contract::load_at(Uint::from(offset)).calldata;
let mut actions = instantiate("contracts/MLoad.sol", "MLoad");
actions.append(&mut vec![
Call {
origin: TestAddress::Alice,
dest: TestAddress::Instantiated(0),
value: 0,
gas_limit: None,
storage_deposit_limit: None,
data,
},
VerifyCall(VerifyCallExpectation {
success: false,
..Default::default()
}),
]);
let results = Specs {
actions,
differential: true,
..Default::default()
}
.run();
let CallResult::Exec { result, .. } = results.last().unwrap() else {
unreachable!()
};
assert_eq!(result.weight_consumed, GAS_LIMIT);
}