sway: The contract function returns wrong value
Issue: Incorrect Return Value from Contract Function
Summary
During the development of Spark Perps, we encountered a peculiar bug where the contract function vault::get_free_collateral_by_token() returns an incorrect value. Despite hardcoding a value within the function for testing, the returned value does not match the expected hardcoded value. This issue seems to be related to how forc compiles the contract, as the discrepancy is observed both in local tests and on the beta-5 test network.
Steps to Reproduce
-
Clone the Spark Perps repository and check out the branch with the reported issue (if you don’t have a dotup, message me on t.me/defi_defiler):
git clone git@github.com:compolabs/spark-perps.git cd spark-perps git checkout bug-failed-collateral-test forc build cargo test --package spark-perps --test integration_tests -- get_free_collateral::get_free_collateral_test --exact --nocapture -
Observe the output of the
get_free_collateral::get_free_collateral_testwhich demonstrates the incorrect return value from the contract function.
Detailed Description
The function get_free_collateral_by_token is expected to return a hardcoded value of 2063986620 for testing purposes. However, the test logs indicate a returned value of 4000000000, suggesting a discrepancy in the function’s execution or return process.
-
Hardcoded function for reference:
#[storage(read)] fn get_free_collateral_by_token(trader: Address, token: AssetId) -> u64 { let mut amount = 0; amount = get_free_collateral_by_token(trader, token); amount = 2063986620; return amount; } -
Observation: Commenting out the line
amount = get_free_collateral_by_token(trader, token);, rebuilding the contract, and rerunning the test yields the expected hardcoded value:#[storage(read)] fn get_free_collateral_by_token(trader: Address, token: AssetId) -> u64 { let mut amount = 0; // amount = get_free_collateral_by_token(trader, token); amount = 2063986620; return amount; }
Toolchain Configuration
fuel-toolchain.toml:[toolchain] channel = "latest-aarch64-apple-darwin" [components] forc = "0.49.3" fuel-core = "0.22.1"
Additional Information
This issue may point towards a potential bug in the forc compiler or the way it handles function returns. Any insights or fixes would be greatly appreciated.
Thank you for your attention to this matter.
Alex, Composability labs
About this issue
- Original URL
- State: closed
- Created 3 months ago
- Comments: 17 (8 by maintainers)
@ironcev the function is not self-recursive, as that’s inside an
implblock and calls a second function. This indeed is a miscompile. I reproduced it locally as well.I was able to minimize the called function inside the codebase to this while still keeping the same miscompile:
where
Curiously, rewriting the original function to:
Logs the following values for amount:
0,1,2063986620, so the register/variable is updated correctly, the function just returns an incorrect value.Looking into
forc build --finalized-asm, I just cannot see the log statements at all. Same withforc parse-bytecodefrom the output binary. Not sure if this has anything to do with the actual issue above, but seemed to be worth a mention.Sadly this is far as I got. Someone from @FuelLabs/sway-compiler should pick this one up.
Out of a quick glance at the function,
get_free_collateral_by_tokenis an endlessly recursive function. Sway does not support recursions at moment and actually I would expect a compiler error here saying that the function is recursive. However, even if recursions were supported, the above definition would lead to endless recursion means running the code until running out of gas.