solmate icon indicating copy to clipboard operation
solmate copied to clipboard

Add compact string encoding library

Open d1ll0n opened this issue 3 years ago • 0 comments

Description

Adds utils/PackedStringLib.sol - a library for efficiently encoding strings that are <=31 bytes.

  • Encodes input strings by putting the length in the first byte and the body in the following 31 bytes.
  • Decodes strings by clearing two words in memory (to ensure the string has leading and trailing zeroes) and then writing the packed form to the last byte of the length buffer (first word), which also places the right-padded body of the string where it needs to be.

Solidity's built-in mechanism for accessing storage strings is efficient when strings can be any size, but in practice most tend to be quite small and static. This means that all of the additional code for determining the type of string (single or multiple word), looping over words and hashing each index to get the slot, goes totally unused. Surprisingly, this can add up to several hundred (or even thousand!) bytes depending on your optimization settings, and can really eat into available contract space.

Below is a comparison of the simplest use-case (retrieving a contract's name) with packed vs. standard strings and constant/immutable vs. storage.

contracts

I tried to stick to the coding conventions as much as possible, but this file has a lot more comments than most - had a bit of an ADHD moment. @transmissions11 if you prefer to keep to the clean aesthetic I'm happy to remove them.

I'm also a little new to Forge, so I'd appreciate a second opinion on whether there are any gaps in the testing.

Checklist

Ensure you completed all of the steps below before submitting your pull request:

  • [x] Ran forge snapshot?
  • [x] Ran npm run lint?
  • [x] Ran forge test?

d1ll0n avatar Sep 18 '22 09:09 d1ll0n