Skip to content

Commit

Permalink
Local with upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
0x19 committed Jul 29, 2024
1 parent 2185b26 commit 9067b4c
Show file tree
Hide file tree
Showing 15 changed files with 90 additions and 71 deletions.
9 changes: 8 additions & 1 deletion abi/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func (b *Builder) processContract(contract *ir.Contract) (*Contract, error) {

// Process state variables.
for _, stateVar := range contract.GetStateVariables() {
// Some old contracts will have this broken. It's related to 0.4 contracts.
// Better to have at least something then nothing at all in this point.
if stateVar.Name == "" && stateVar.GetTypeDescription() == nil {
continue
}
method := b.processStateVariable(stateVar)
toReturn = append(toReturn, method)
}
Expand Down Expand Up @@ -143,7 +148,9 @@ func (b *Builder) buildMethodIO(method MethodIO, typeDescr *ast.TypeDescription)
}
method.InternalType = typeDescr.GetString()
case "struct":
return b.resolver.ResolveStructType(typeDescr)
structMember := b.resolver.ResolveStructType(typeDescr)
structMember.Name = method.Name
return structMember
default:
method.Type = typeName
method.InternalType = typeDescr.GetString()
Expand Down
5 changes: 0 additions & 5 deletions abi/state_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package abi

import (
"github.com/unpackdev/solgo/ir"
"github.com/unpackdev/solgo/utils"
)

// processStateVariable processes the provided StateVariable from the IR and constructs a Method representation.
Expand All @@ -17,10 +16,6 @@ func (b *Builder) processStateVariable(stateVar *ir.StateVariable) *Method {
StateMutability: b.normalizeStateMutability(stateVar.GetStateMutability()),
}

if stateVar.GetTypeDescription() == nil {
utils.DumpNodeWithExit(stateVar)
}

typeName := b.resolver.ResolveType(stateVar.GetTypeDescription())

switch typeName {
Expand Down
5 changes: 2 additions & 3 deletions ast/modifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,9 @@ func (m *ModifierDefinition) ParseDefinition(
parameters.Src = m.Src
}
m.Parameters = parameters

bodyNode := NewBodyNode(m.ASTBuilder, false)
if ctx.Block() != nil && !ctx.Block().IsEmpty() {
bodyNode := NewBodyNode(m.ASTBuilder, false)
bodyNode.ParseBlock(unit, contractNode, m, ctx.Block())
m.Body = bodyNode

if ctx.Block().AllUncheckedBlock() != nil {
for _, uncheckedCtx := range ctx.Block().AllUncheckedBlock() {
Expand All @@ -229,6 +227,7 @@ func (m *ModifierDefinition) ParseDefinition(
}
}
}
m.Body = bodyNode

m.currentModifiers = append(m.currentModifiers, m)
return m
Expand Down
18 changes: 14 additions & 4 deletions ast/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,21 @@ func (p *Parameter) Parse(unit *SourceUnit[Node[ast_pb.SourceUnit]], fnNode Node
p.TypeDescription = typeName.GetTypeDescription()
p.currentVariables = append(p.currentVariables, p)

if refId, refTypeDescription := p.GetResolver().ResolveByNode(typeName, typeName.Name); refTypeDescription != nil {
typeName.ReferencedDeclaration = refId
typeName.TypeDescription = refTypeDescription
p.TypeDescription = typeName.GetTypeDescription()
if p.TypeDescription == nil {
if refId, refTypeDescription := p.GetResolver().ResolveByNode(typeName, typeName.Name); refTypeDescription != nil {
typeName.ReferencedDeclaration = refId
typeName.TypeDescription = refTypeDescription
p.TypeDescription = typeName.GetTypeDescription()
}
}

if p.Name == "" && p.TypeName != nil && p.TypeName.Name != "" {
p.Name = p.TypeName.Name
}

/* if p.Id == 4253 {
utils.DumpNodeWithExit(p)
}*/
}

// ParseEventParameter parses the event parameter context and populates the Parameter fields for event parameters.
Expand Down
7 changes: 7 additions & 0 deletions ast/primary_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,13 @@ func (p *PrimaryExpression) Parse(
}
}

if ctx.GetText() == "throw" {
p.TypeDescription = &TypeDescription{
TypeIdentifier: "t_magic_throw",
TypeString: "throw",
}
}

if ctx.GetText() == "block" {
p.TypeDescription = &TypeDescription{
TypeIdentifier: "t_magic_block",
Expand Down
10 changes: 6 additions & 4 deletions ast/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ func (r *Resolver) ResolveByNode(node Node[NodeType], name string) (int64, *Type
isPrefixSlice := strings.HasPrefix(name, "[]")
cleanedName := name

if isSlice {
cleanedName = strings.TrimSuffix(name, "[]")
} else if isPrefixSlice {
cleanedName = strings.TrimPrefix(name, "[]")
if isSlice || isPrefixSlice {
cleanedName = strings.ReplaceAll(name, "[]", "")
}

rNode, rNodeType := r.resolveByNode(cleanedName, node)
Expand Down Expand Up @@ -479,6 +477,10 @@ func (r *Resolver) byEvents(name string) (int64, *TypeDescription) {
}

func (r *Resolver) byGlobals(name string) (int64, *TypeDescription) {
if strings.Contains(name, "[]") {
name = strings.ReplaceAll(name, "[]", "")
}

for _, node := range r.globalDefinitions {
switch nodeCtx := node.(type) {
case *EnumDefinition:
Expand Down
35 changes: 25 additions & 10 deletions ast/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (t *TypeName) StorageSize() (int64, bool) {
if strings.Contains(t.GetTypeDescription().GetString(), "int_const") {
rationalParts := strings.Split(t.GetTypeDescription().GetIdentifier(), "_by_")
if len(rationalParts) == 2 {
numerator, err1 := strconv.Atoi(rationalParts[0][len(rationalParts[0])-2:])
numerator, err1 := strconv.Atoi(strings.Replace(rationalParts[0], "t_rational_", "", -1))
denominator, err2 := strconv.Atoi(rationalParts[1])
if err1 == nil && err2 == nil {
bitSize := int64(math.Ceil(math.Log2(float64(numerator / denominator))))
Expand Down Expand Up @@ -91,8 +91,17 @@ func elementaryTypeSizeInBits(typeName string) (int64, bool) {
// `bytes` with a fixed size, and dynamically sized types like `string` and `bytes`.
// Returns the size and a boolean indicating if the type is recognized.
func getTypeSizeInBits(typeName string) (int64, bool) {
// TODO: Make this actually work better... Figure out dynamically what is the size of an array
typeName = strings.TrimSuffix(typeName, "[]")
// Handle array types
if strings.HasSuffix(typeName, "[]") {
elementType := strings.TrimSuffix(typeName, "[]")
elementSize, ok := getTypeSizeInBits(elementType)
if !ok {
return 0, false
}
// For dynamic arrays, the size in bits depends on the actual content
// and includes the overhead for array length (256 bits).
return elementSize + 256, true
}

switch {
case typeName == "bool":
Expand All @@ -113,21 +122,27 @@ func getTypeSizeInBits(typeName string) (int64, bool) {
}

return int64(bitSize), true

case typeName == "string":
// Dynamic-size types; the size depends on the actual content.
// It's hard to determine the exact size in bits without the content.
// Returning a default size for the pointer.
return 256, true
case typeName == "bytes":
// Dynamic-size types; the size depends on the actual content.
// It's hard to determine the exact size in bits without the content.
// Returning a default size for the pointer.
return 256, true
case strings.HasPrefix(typeName, "bytes"):
byteSizeStr := strings.TrimPrefix(typeName, "bytes")
if byteSizeStr == "" {
return 0, false // Dynamic-sized bytes array, which is not supported
}
byteSize, err := strconv.Atoi(byteSizeStr)
if err != nil || byteSize < 1 || byteSize > 32 {
return 0, false
}
return int64(byteSize) * 8, true

case typeName == "string", typeName == "bytes":
// Dynamic-size types; the size depends on the actual content.
// It's hard to determine the exact size in bits without the content.
// Returning a default size for the pointer.
return 256, true

default:
return 0, false // Type not recognized
}
Expand Down
4 changes: 2 additions & 2 deletions ast/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ func (t *Tree) UpdateNodeReferenceById(nodeId int64, nodeRefId int64, typeRef *T
return false
}

for _, child := range t.astRoot.GetNodes() {
for _, child := range t.astRoot.GetGlobalNodes() {
if n := t.byRecursiveReferenceUpdate(child, nodeId, nodeRefId, typeRef); n {
return n
}
}

for _, child := range t.astRoot.GetGlobalNodes() {
for _, child := range t.astRoot.GetNodes() {
if n := t.byRecursiveReferenceUpdate(child, nodeId, nodeRefId, typeRef); n {
return n
}
Expand Down
22 changes: 1 addition & 21 deletions ast/type_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,10 @@ func (t *TypeName) SetReferenceDescriptor(refId int64, refDesc *TypeDescription)
if strings.HasSuffix(t.Name, "[]") && refDesc != nil {
if !strings.HasSuffix(refDesc.TypeString, "[]") {
t.TypeDescription.TypeString += "[]"
/*if t.PathNode != nil && t.PathNode.TypeDescription != nil {
if !strings.HasSuffix(t.PathNode.Name, "[]") {
if strings.HasSuffix(t.PathNode.TypeDescription.TypeString, "[]") {
// Kumbayaa through fucking recursion...
t.PathNode.TypeDescription.TypeString = strings.TrimSuffix(
t.PathNode.TypeDescription.TypeString, "[]",
)
}
}
}*/
return true
}
}

// Lets update the parent node as well in case that type description is not set...
/* parentNodeId := t.GetSrc().GetParentIndex()
if parentNodeId > 0 {
if parentNode := t.GetTree().GetById(parentNodeId); parentNode != nil {
if parentNode.GetTypeDescription() == nil {
parentNode.SetReferenceDescriptor(refId, refDesc)
}
}
}
*/
return true
}

Expand Down
4 changes: 3 additions & 1 deletion contracts/constructor.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func (c *Contract) DiscoverConstructor(ctx context.Context) error {
abiRoot != nil && abiRoot.GetEntryContract().GetMethodByType("constructor") != nil {
cAbi, _ := utils.ToJSON(abiRoot.GetEntryContract().GetMethodByType("constructor"))
constructorAbi := fmt.Sprintf("[%s]", string(cAbi))
//utils.DumpNodeWithExit(abiRoot.GetEntryContract().GetMethodByType("constructor"))
//utils.DumpNodeWithExit(irRoot.GetEntryContract().GetConstructor().GetParameters())
tx := c.descriptor.Transaction
deployedBytecode := c.descriptor.DeployedBytecode
Expand All @@ -50,7 +51,8 @@ func (c *Contract) DiscoverConstructor(ctx context.Context) error {

// TODO: Fix
// - 0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936 (239 bytes more) - Some shitty text...

//spew.Dump(hex.EncodeToString(tx.Data()))
//fmt.Println("")
//spew.Dump(hex.EncodeToString(adjustedData[constructorDataIndex:]))
//spew.Dump(constructorAbi) // 239
//utils.DumpNodeWithExit(irRoot.GetEntryContract().GetConstructor().GetParameters())
Expand Down
4 changes: 4 additions & 0 deletions ir/function_call.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ir

import (
"github.com/unpackdev/solgo/utils"
"strings"

v3 "github.com/cncf/xds/go/xds/type/v3"
Expand Down Expand Up @@ -139,6 +140,9 @@ func (b *Builder) processFunctionCall(fn *Function, unit *ast.FunctionCall) *Fun
}

for _, arg := range unit.GetArguments() {
if arg.GetTypeDescription() == nil {
utils.DumpNodeWithExit(arg)
}
toReturn.ArgumentTypes = append(toReturn.ArgumentTypes, arg.GetTypeDescription().ToProto())
}

Expand Down
20 changes: 8 additions & 12 deletions ir/standards.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package ir
import (
ir_pb "github.com/unpackdev/protos/dist/go/ir"
"github.com/unpackdev/solgo/standards"
"github.com/unpackdev/solgo/utils"
)

// Standard represents a specific Ethereum Improvement Proposal standard that a contract may adhere to.
Expand Down Expand Up @@ -70,25 +69,22 @@ func (b *Builder) processEips(root *RootSourceUnit) {
outputs := make([]standards.Output, 0)

for _, param := range function.GetParameters() {
if param.GetTypeDescription() == nil {
//utils.DumpNodeWithExit(param)
}
inputs = append(inputs, standards.Input{
Type: param.GetTypeDescription().GetString(),
Indexed: false, // Specific to events...
})
}

for _, ret := range function.GetReturnStatements() {
if ret.GetTypeDescription() != nil {
outputs = append(outputs, standards.Output{
Type: "t_unknown", // Will fix this later on with upgrade of parser to support solidity 0.5+
})
} else {
if ret.GetTypeDescription() == nil {
utils.DumpNodeWithExit(function)
}
outputs = append(outputs, standards.Output{
Type: ret.GetTypeDescription().GetString(),
})
if ret.GetTypeDescription() == nil {
//utils.DumpNodeWithExit(function)
}
outputs = append(outputs, standards.Output{
Type: ret.GetTypeDescription().GetString(),
})
}

contract.Functions = append(contract.Functions, standards.StandardFunction{
Expand Down
7 changes: 3 additions & 4 deletions ir/variables.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ir

import (
"github.com/unpackdev/solgo/utils"
"strings"

ast_pb "github.com/unpackdev/protos/dist/go/ast"
Expand Down Expand Up @@ -128,9 +127,9 @@ func (b *Builder) processStateVariables(unit *ast.StateVariableDeclaration) *Sta

// It could be that the name of the type name node is not set, but the type description string is.
if variableNode.Type == "" {
if variableNode.TypeDescription == nil {
utils.DumpNodeWithExit(variableNode)
}
/* if variableNode.TypeDescription == nil {
utils.DumpNodeWithExit(variableNode)
}*/
variableNode.Type = variableNode.TypeDescription.TypeString
}

Expand Down
5 changes: 4 additions & 1 deletion parser/solidity_parser.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions storage/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package storage
import (
"context"
"fmt"
"github.com/unpackdev/solgo/utils"
"strings"
)

Expand Down Expand Up @@ -75,8 +74,9 @@ func (r *Reader) CalculateStorageLayout() error {
for _, variable := range variables {
storageSize, found := variable.GetAST().GetTypeName().StorageSize()
if !found {
utils.DumpNodeWithExit(variable.GetAST().GetTypeName())
return fmt.Errorf("error calculating storage size for variable: %s", variable.GetName())
//utils.DumpNodeNoExit(variable.GetAST().GetTypeName())
//return fmt.Errorf("error calculating storage size for variable: %s", variable.GetName())
continue
}

typeName := variable.GetType()
Expand Down

0 comments on commit 9067b4c

Please sign in to comment.