blockscout / blockscout-rs

MIT License
140 stars 100 forks source link

[Verifier] Cannot verify yul contracts starting from solc v0.8.21 #934

Open rimrakhimov opened 1 week ago

rimrakhimov commented 1 week ago

Verification of yul contracts compiled with compilers greater or equal than solc v0.8.21 fails with internal server error. Logged error:

SerdeJson(Error("unknown variant `YulObject`, expected one of `Assignment`, `BinaryOperation`, `Conditional`, `ElementaryTypeNameExpression`, `FunctionCall`, `FunctionCallOptions`, `Identifier`, `IndexAccess`, `IndexRangeAccess`, `Literal`, `MemberAccess`, `NewExpression`, `TupleExpression`, `UnaryOperation`, `Block`, `Break`, `Continue`, `DoWhileStatement`, `EmitStatement`, `ExpressionStatement`, `ForStatement`, `IfStatement`, `InlineAssembly`, `PlaceholderStatement`, `Return`, `RevertStatement`, `TryStatement`, `UncheckedBlock`, `VariableDeclarationStatement`, `VariableDeclaration`, `WhileStatement`, `YulAssignment`, `YulBlock`, `YulBreak`, `YulContinue`, `YulExpressionStatement`, `YulLeave`, `YulForLoop`, `YulFunctionDefinition`, `YulIf`, `YulSwitch`, `YulVariableDeclaration`, `YulFunctionCall`, `YulIdentifier`, `YulLiteral`, `YulLiteralValue`, `YulHexValue`, `ContractDefinition`, `FunctionDefinition`, `EventDefinition`, `ErrorDefinition`, `ModifierDefinition`, `StructDefinition`, `EnumDefinition`, `UserDefinedValueTypeDefinition`, `PragmaDirective`, `ImportDirective`, `UsingForDirective`, `SourceUnit`, `InheritanceSpecifier`, `ElementaryTypeName`, `FunctionTypeName`, `ParameterList`, `TryCatchClause`, `ModifierInvocation`, `Other`", line: 1, column: 8791), ))

How to reproduce

https://eth-sepolia.blockscout.com/address/0x349B7Ac9681c8c88b2DED03828a50520CeCe7AD1

Should be verified with solc v0.8.26+commit.8a97fa7a, without any optimization, default evmVersion and following sources

object "Proxy" {
    // deployment code
    code {
        let size := datasize("runtime")
        datacopy(0, dataoffset("runtime"), size)
        return(0, size)
    }
    object "runtime" {
        // deployed code
        code {
            calldatacopy(0, 0, calldatasize())
            let result := create2(callvalue(), 0, calldatasize(), 0)
            if iszero(result) { revert(0, 0) }
            mstore(0, result)
            return(12, 20)
        }
    }
}
rimrakhimov commented 1 week ago

Tried to remove the ast from outputSelection completely by not specifying it in file-level values. Didn't work due to https://github.com/ethereum/solidity/issues/14452