Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Implement ERC1155Proxy and StaticCallProxy in Solidity #1963

Merged
merged 5 commits into from
Jul 17, 2019

Conversation

abandeali1
Copy link
Member

@abandeali1 abandeali1 commented Jul 16, 2019

Description

  • Implements the ERC1155Proxy and StaticCallProxy in Solidity
  • Note: StaticCallProxy cannot inherit IAssetProxy because its transferFrom function is marked as view.
  • Many revert conditions no longer contain reasons, as they are handled within Solidity
  • There are no longer any checks for if the length of assetData is a multiple of 32. However, any lengths less than required should fail (TODO: add tests for this)
  • Found some pretty bizarre behavior is Solidity's abi.decode. When multiple offsets point to the same location in calldata (i.e if values == ids) then the decoded output is also copied to the same location in memory. This means we cannot modify values directly, or we may end up modifying ids or data as well.
  • Thoughts on using slice vs sliceDestructive here? I opted for sliceDestructive because assetData is not reused, it is cheaper, and the implementation is arguably simpler.

TODO: gas benchmarking

Testing instructions

Types of changes

Checklist:

  • Prefix PR title with [WIP] if necessary.
  • Add tests to cover changes as needed.
  • Update documentation as needed.
  • Add new entries to the relevant CHANGELOG.jsons.

uint256[] memory values,
bytes memory data
) = abi.decode(
assetData.sliceDestructive(4, assetData.length),
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm surprised this works with assetData being calldata and not memory. Is it cloning assetData to memory at the time of this call?

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe calldata gets copied to memory when you pass it into any internal function (sliceDestructive in this case). That might not be implemented for things that require ABIv2 encoding, though (or maybe just structs?).

Copy link
Contributor

@dorothy-zbornak dorothy-zbornak left a comment

Choose a reason for hiding this comment

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

RIP assembly 👍

);

// Execute staticcall
(bool success, bytes memory returnData) = staticCallTarget.staticcall(staticCallData);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be doing an extcodesize() check to safeguard people from accidentally calling EOAs? Could be a problem if people expect a keccak(bytes(0)) result.

At the very least, we should add a test that confirms that calling an EOA results in keccak(bytes(0)).

Copy link
Member Author

Choose a reason for hiding this comment

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

I will add a test for this, but it feels a bit excessive to me to add an extcodesize or extcodehash check here. You really have to know the interface of and trust the staticCallTarget beforehand in order to use this.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.007%) to 83.296% when pulling 53136ca on feat/contracts/non-asm-proxies into 6d6e7e1 on development.

@abandeali1 abandeali1 merged commit 9dbc9a8 into development Jul 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants