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

add claimCompressed #238

Merged
merged 19 commits into from
Dec 19, 2023
Merged

add claimCompressed #238

merged 19 commits into from
Dec 19, 2023

Conversation

waynehoover
Copy link
Contributor

@waynehoover waynehoover commented Dec 13, 2023

Non breaking changes

  • Adds new claimCompressed function for optimized calldata, it just forwards to claimOptimized, so no breaking changes.
  • Removes the QuestCreatedWithAction event as it wasn't used.
  • Removes the ability to create sablier quests in the factory, as it was complicating things and it's not currently used.
  • Adds new createERC20Quest and createERC1155Quest functions that include two new string params: actionType_ and questName_.

Deployment plan

  • Because this depends on new state being saved on quest creation, i.e. questName and actionType the new claimCompressed function not work on any quests that don't have this data saved on chain, this function should only be used on quests that have this data.
  • When this is deployed we need to change the ABI where used when creating quests to use the new functions

Ideas for further reducing claim calldata

  • Create a forwarding contract that only has a fallback, to remove the need for a function selector.
  • use abi.encodePacked to encode the calldata and calldataload to get data from offset (not recommended if ever plan to pass dynamic types), this would remove the need for LibZip
  • use a lookup enum passing the chainid

@waynehoover waynehoover requested a review from a team as a code owner December 13, 2023 02:04
@waynehoover waynehoover changed the title add claimOptimized add claimCompressed Dec 13, 2023
@waynehoover waynehoover requested a review from Quazia December 15, 2023 02:13
Copy link
Member

@Quazia Quazia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - tried to signal to anywhere I see room for future improvements but I think this is good as is. Do with my comments what you wish

@@ -147,6 +148,7 @@ contract QuestFactory is Initializable, LegacyStorage, OwnableRoles, IQuestFacto
/// @param totalParticipants_ The total amount of participants (accounts) the quest will have
/// @param tokenId_ The reward token id of the erc1155 at rewardTokenAddress_
/// @param questId_ The id of the quest
/// @param actionType_ The action type for the quest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add questName_ to params

bytes memory uuid = new bytes(36); // UUID length with hyphens

uint256 j = 0; // Position in uuid
for (uint256 i = 0; i < 16; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can do this with a single index vs 2 if we keep the j++ statements and do a while instead of a for. I think it'd be possible with a for too just without the third statement. Not sure if this is worth it though - as we've found compute is cheap!

));
}

function bytes16ToUUID(bytes16 data) public pure returns (string memory) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you comment the encoding and expectations around the form of the bytes16 data here?

(
address ref,
bytes32 txHash,
uint32 txHashChainId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's few enough chains that we could use a smaller value here and then leverage a lookup table - uint8 should work fine for.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to capture this for a follow-on just trying to see where else we could trim the call data

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added notes in the description about possible ways to get the bytes down in the future.

@@ -293,6 +247,68 @@ contract QuestFactory is Initializable, LegacyStorage, OwnableRoles, IQuestFacto
/*//////////////////////////////////////////////////////////////
CLAIM
//////////////////////////////////////////////////////////////*/
function claimCompressed(bytes calldata compressedData) external payable {
bytes memory data = LibZip.cdDecompress(compressedData);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wild - do we know if ordering effects the efficiency of the compression at all? That code is hard to parse.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ordering does, generally you want to have zero bytes in the middle.

bytes16 questid,
bytes32 r,
bytes32 vs
) = abi.decode(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put the params smaller than a block at the end? I don't think it matters here but generally good form.

(address, bytes32, uint32, bytes16, bytes32, bytes32)
);

string memory questIdString = bytes16ToUUID(questid);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So cool - love this. I'm surprised there's not an off-the-shelf bytes16toUUID util. Maybe we can ask for one in solady/solmate and import that once the optomizzeeddd version is available wdyt? Again though, not super important since apparently compute is so cheap on L2


string memory questIdString = bytes16ToUUID(questid);
Quest storage quest = quests[questIdString];
string memory jsonData = buildJsonString(uint256(txHash).toHexString(), uint256(txHashChainId).toString(), quest.actionType, quest.questName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah - here is where you're pulling that back in. Totally makes sense now.

return string(uuid);
}


function claimOptimized(bytes calldata signature_, bytes calldata data_) external payable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should change the visibility of this to internal or public if we're using it internally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to keep it external so that it's backwards compatible. Eventually once everyone is using the new function we can make it internal.

@waynehoover waynehoover merged commit e03e6ce into main Dec 19, 2023
2 checks passed
@waynehoover waynehoover deleted the reduced_calldata_proxy branch December 19, 2023 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants