Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Library call function is not an instance of Function #1622

Open
0xalpharush opened this issue Jan 23, 2023 · 6 comments
Open

[Bug]: Library call function is not an instance of Function #1622

0xalpharush opened this issue Jan 23, 2023 · 6 comments
Labels
bug Something isn't working High Priority
Milestone

Comments

@0xalpharush
Copy link
Contributor

Describe the issue:

Library call function is not an instance of Function
Related with this library call here https://github.com/code-423n4/2023-01-timeswap/blob/ef4c84fb8535aad8abd6b67cc45d994337ec4514/packages/v2-option/src/TimeswapV2Option.sol#L112

Code example to reproduce the issue:

git clone https://github.com/code-423n4/2023-01-timeswap
yarn
cd v2-token
slither .

Version:

0.9.2

Relevant log output:

File "/Users/alpharush/tob/slither/slither/core/cfg/node.py", line 920, in _find_read_write_call
    assert isinstance(ir.function, Function)
AssertionError
@0xalpharush 0xalpharush added bug Something isn't working High Priority labels Jan 23, 2023
@0xGusMcCrae
Copy link
Contributor

I tried to figure this out after noticing it in the c4 audit for timeswap.

As far as I can tell, the issue is that v2-option, v2-pool, and v2-token all have ParamLibrary contracts with check functions in their respective structs/Param.sol files. When they are used in the same directory, as they are in packages/v2-pool and packages/v2-token, slither mixes up the ParamLibraries.

The issue appears to be with ParamLibrary.check(param), which is only present in v2-pool and v2-token's ParamLibrary. v2-option's ParamLibrary.check functions all have a second parameter, blockTimestamp. The assertion error occurs while slither is processing ParamLibrary.check in both TimeswapV2Token.sol and TimeswapV2Pool.sol.

I added some print statements throughout slither to try to debug.

in slither/slithir/convert.py (around line 100):

def convert_expression(expression, node):
# handle standlone expression
# such as return true;
from slither.core.cfg.node import NodeType

print("beginning of convert_expression")
print(expression)
try:
    print(expression.called.expression.value.file_scope)
    print([f.name for f in expression.called.expression.value.functions])
except:
    None

Running slither . in packages/v2-token:

beginning of convert_expression
ParamLibrary.check(param)
../v2-option/src/structs/Param.sol
['check', 'check', 'check', 'check']
Traceback (most recent call last):
(error is thrown here)

This is occurring in TimeswapV2Token.mint(TimeswapV2TokenMintParam) (as you've stated above). It's using check(TimeswapV2TokenMintParam memory param) from v2-token's ParamLibrary.

Running slither . in packages/v2-pool gets the same result:

beginning of convert_expression
ParamLibrary.check(param)
../v2-option/src/structs/Param.sol
['check', 'check', 'check', 'check']
Traceback (most recent call last):
(error is thrown here)

This one was occurring in TimeswapV2Pool.collectProtocolFees(TimeswapV2PoolCollectParam). This time it's using check(TimeswapV2PoolCollectParam memory param) from v2-pool's ParamLibrary.

All of v2-option's ParamLibrary.check functions have an additional uint96 input blockTimestamp, so the expression ParamLibrary(check) can't belong to v2-option's ParamLibrary. But in both cases, the expression's node is giving the v2-option param.sol file as its file_scope and listing its parent contract functions as being 4 check functions, which is only valid for v2-option since v2-pool's ParamLibrary has 6 check functions and v2-token's ParamLibrary has 5 functions.

I haven't been able to pinpoint where the mismatch is originating, but it appears that there's some sort of incorrect assignment that matches the v2-pool and v2-token ParamLibrary.check functions to v2-option's ParamLibrary file and contract. I tried to backtrack to find the error but kind of hit a dead end. If someone more familiar with the codebase knows where this might be occurring, I could take another look and try to fix it.

I have no idea why this is causing it to throw an AssertionError on isinstance(ir.function, Function), but something is going wrong here.

@0xalpharush
Copy link
Contributor Author

@0xGusMcCrae, thanks for taking the time tracking this down. Based off the duplicate function names, I suspect this may be fixed by #1625 but I need to double check

@0xalpharush 0xalpharush added this to the 0.9.4 milestone Apr 4, 2023
@smonicas
Copy link
Contributor

To add something more the issue appears when parsing an expression. The find_variable returns the ParamLibrary with 4 functions always because it's found in the currect scope.

var, was_created = find_variable(value, caller_context, referenced_declaration)

contracts = current_scope.contracts
if var_name in contracts:
return contracts[var_name], False

@0xalpharush
Copy link
Contributor Author

0xalpharush commented Apr 11, 2023

@smonicas this is similar to the issue outlined in #1809 (comment)
ref #1809

@smonicas
Copy link
Contributor

The problem is that contracts is a dict with key the contract name however when updating with the new accessible contracts will overwrite the older contract with the same name even if it's actually a different contract (e.g. in a different file).

self.contracts: Dict[str, Contract] = {}

if not _dict_contain(new_scope.contracts, self.contracts):
self.contracts.update(new_scope.contracts)
learn_something = True

@0xalpharush
Copy link
Contributor Author

0xalpharush commented Apr 7, 2024

Any issue that can be fixed directly in Slither is fixed in #2404 so this is blocked on foundry-rs/foundry#7591

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working High Priority
Projects
None yet
Development

No branches or pull requests

3 participants