paritytech / paritytech/revive

[SRLabs] [Info] Discrepencies in handling of yul object blocks

Open
#351 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
102
Forks
26
Avg merge
1d 13h
Merged PRs (30d)
6

Description

Issue Description

resolc differs in the handling of objects from solidity, breaking common patterns. There are two primary scenarios which are affected and both are undocumented.

Usage of multiple objects

In solidity, multiple objects may be used as code blocks for subsequent use or for complex deployment strategies. resolc assumes that every object is a contract and will error if it is unable to find the contract in the build chain. Note that the --yul mode currently allows for only one file.

Poc
object "Test" {
        code {
	stop()
	}
    object "Test_deployed" {
    	code {}
    }
    object "Error" {
	code {}
    }
}	

When compiling with resolc

thread 'main' panicked at crates/solidity/src/project/mod.rs:129:33:
Dependency `Error` full path not found
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Dotted access for nested objects

In yul, nested objects may be accessed with the dot notation.

Data objects or sub-objects whose names contain a . can be defined but it is not possible to access them through datasize, dataoffset or datacopy because . is used as a separator to access objects inside another object.

This is currently not possible with resolc and results in a LLVM-IR generation error.

PoC
object "Test" {
        code {
        function allocate(size) -> ptr {
            ptr := mload(0x40)
            if iszero(ptr) { ptr := 0x60 }
            mstore(0x40, add(ptr, size))
        }
        let size := datasize("Test_deployed.Test")
        let offset := allocate(size)
        datacopy(offset, dataoffset("Test_deployed.Test"), size)
        return(offset, size)
    }
    object "Test_deployed" {
        code { 
            stop()
	    }
        object "Test" {
            code {
	    	revert(0,0)
            }
        }
    }
}

When compiling with resolc

Contract `test.yul` compiling error: 
The contract `test.yul` LLVM IR generator definition pass error: 
Contract with identifier `Test_deployed.Test` not found in the projectThe contract `test.yul` 
LLVM IR generator definition pass error: Contract with identifier `Test_deployed.Test` not found in the project

Risk

While there is no risk, these cases should be handled with appropriate errors.

Mitigation

Handle these scenarios with appropriate errors.
The first scenario may be fixed by handling the presence of multiple objects with a graceful error and exit.

For the second scenario, either implement nested object access or error when a . is used in an object identifier.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce both Yul object-block examples and start at crates/solidity/src/project/mod.rs:129, where the multiple-object dependency failure is reported. Trace the project lookup and LLVM IR generation paths mentioned in the errors. Done means both cases produce appropriate errors, or nested dotted-object access is implemented as specified by the issue.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.