argotorg / argotorg/solidity

Unsafe type conversions with the IR codegen

Open
#15,142 1 comment 1 reaction 0 assignees View on GitHub
bug :bug:
Dominant language
C++
Stars
25.7k
Forks
6.2k
Avg merge
2d 19h
Merged PRs (30d)
29

Description

## Description

With legacy codegen, when `uint40` is returned from a function, the value is truncated. In the code below, if a value larger than `uint40` is passed to `getNumber`, it is truncated to 40 bits. This means that the results of `getNumber(0)` and `getNumber(2**40)` are the same.

With `viaIR` codegen, the value is not truncated and some garbage remains in memory. Thus, the actual index accessed in the `numbers` array is not correct, so executing `getNumber(2**40)` results in an 'Array index out of bound' panic error.

## Environment

- Compiler version: 0.8.25
- Target EVM version (as per compiler settings): default
- Operating system: MacOS 14 Sonoma

## Steps to Reproduce

```solidity
contract Foo {
uint256[] internal numbers;

function addNumber(uint256 number) public {
numbers.push(number);
}

function getNumber(uint256 index) public view returns (uint256) {
return numbers[_convertToUint40(index)];
}

function _convertToUint40(uint256 n) internal pure returns (uint40 result) {
assembly {
result := n
}
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start by compiling and running the Solidity reproducer with legacy and viaIR code generation, focusing on _convertToUint40 and the getNumber(2**40) call. Trace the IR codegen handling of the assembly assignment and add or update a regression test so the viaIR result truncates to uint40 and matches legacy codegen without an out-of-bounds panic.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, solidity
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.