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

Dynamic Strings #4391

Open
stas opened this issue Dec 6, 2024 · 0 comments
Open

Dynamic Strings #4391

stas opened this issue Dec 6, 2024 · 0 comments
Labels
needs triage needs triage

Comments

@stas
Copy link

stas commented Dec 6, 2024

Simple Summary

Velodrome Sugar is an onchain API handling internal and external contract calls. In order to avoid failures to external calls (eg. a random token contract that could be upgraded to a non ERC20 compatible interface), the ERC20 calls are wrapped up for safety using raw_call().

These calls to the ERC20.symbol() do not allow us to dynamically handle arbitrary byte array size returned by the raw_call().

Motivation

There are two aspects in the described limitation.

Consider the following example:

# To test on OP Mainnet, pass these token addresses:
# * 0x4200000000000000000000000000000000000006 (weth)
# * 0x045D841ba37E180bC9b9D4da718E14b9ED7925d6 (large unicode value)

@external
@view
def safe_symbol(_token: address) -> String[10]:
  response: Bytes[100] = raw_call(
      _token,
      method_id("symbol()"),
      max_outsize=100,
      gas=50000,
      is_delegate_call=False,
      is_static_call=True,
      revert_on_failure=False,
  )[1]

  response_len: uint256 = len(response)

  # Min bytes to use abi_decode()
  if response_len > 0 and response_len <= 96:
    return abi_decode(response, String[10])

  return "-???-"
  1. using max_outsize=96 we are not able to get the actual size of the response byte array
  2. even having the actual size of the response we won't be able to use abi_decode() without having support for dynamic string size allocation

Specification

Suggested approach would be to probably

a) extend the return value of the raw_call to return the actual size of the returned bytes, eg. outsize
b) provide support for dynamic string types, eg symbol: String[outsize] = empty(String[outsize])

Backwards Compatibility

  • raw_call() would likely introduce a breaking change for implementations that expect a return value of a tuple with two values
  • dynamic strings support would just extend the existing String interface allowing non-static values to be passed

Dependencies

Might need some help if there are duplicates re this.

References

See attached simple example.

Copyright

Copyright and related rights waived via CC0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage needs triage
Projects
None yet
Development

No branches or pull requests

1 participant