-
Notifications
You must be signed in to change notification settings - Fork 465
Conversation
24e2100
to
302ed95
Compare
82cafd6
to
6fe5fed
Compare
590dbf1
to
c0eef21
Compare
785f1c5
to
6fa806a
Compare
c0eef21
to
49ccb98
Compare
78ec115
to
12eeed4
Compare
9b5199e
to
9822792
Compare
// 4 (function selector) | ||
// + assetDataOffset | ||
// + 32 (length of assetData) | ||
calldatacopy(32, add(36, assetDataOffset), assetDataLength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're probably right, but why not calldatacopy(68, add(36, assetDataOffset), sub(assetDataLength, 36))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question - this line copies the entire assetData into memory at offset 32. Memory allocation looks like this:
32 : assetProxyId
36 : address of ERC1155 contract
68 : offset to tokenIds
...
This is later transformed into:
00 : batchTransferFrom selector
04 : from address
36 : to address
68 : offset to tokenIds
...
If we replaced this line with calldatacopy(68, add(36, assetDataOffset), sub(assetDataLength, 36))
then we would have the following allocation:
68 : assetProxyId
72 : address of ERC1155 contract
104 : offset to tokenIds
...
And it would truncate 36 bytes at the tail end of the asset data.
Note that assetData
is a byte array so it is abi encoded as:
0 : length
32 : contents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Super appreciate the walkthrough.
12eeed4
to
441b379
Compare
// | Header | 0 | 4 | assetProxyId | | ||
// | Params | | 4 * 32 | function parameters: | | ||
// | | 4 | | 1. address of ERC1155 contract | | ||
// | | 36 | | 2. offset to tokenIds (*) | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like these param names should be ids
, values
, and data
to be consistent with the naming of the actual ERC1155 transfer params.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meh, actually we aren't really consistent in the other proxies either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No I agree, we should be consistent with the naming of the ERC1155 transfer params.
// 4 (function selector) | ||
// + assetDataOffset | ||
// + 32 (length of assetData) | ||
calldatacopy(32, add(36, assetDataOffset), assetDataLength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally like annotating calldatacopy
like we do in the MAP here: https://github.com/0xProject/0x-monorepo/blob/development/contracts/asset-proxy/contracts/src/MultiAssetProxy.sol#L161
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this +1.
let scaledTokenValue := mul(tokenValue, scaleAmount) | ||
|
||
// Check if scaled value is zero | ||
if iszero(scaledTokenValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually check if the amount
is 0 in any of the other proxies. What is the reason for doing so here, and can this ever be potentially limiting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mm yeah, here's my reasoning - curious to get your thoughts - in the Exchange we check that the maker/taker amounts are non-zero. This amount is then directly used by the ERC20 and ERC721 proxies, so their check would be redundant. In the case of 1155, any one of the encoded values could also be zero, so I added this check for consistency.
|
||
// Check for multiplication overflow | ||
let expectedTokenValue := div(scaledTokenValue, scaleAmount) | ||
if iszero(eq(expectedTokenValue, tokenValue)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that if we do remove the last check, we'll still need to check if scaleAmount
is 0 before doing this division.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A check has been added above, right after we load amount
.
packages/types/CHANGELOG.json
Outdated
"version": "2.2.3", | ||
"changes": [ | ||
{ | ||
"note": "Added `ERC1155AssetData`, `ERC1155AssetDataNoProxyId`, and `ERC1155AssetDataAbi`", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change can be merged with the previous entry (not yet published).
|
||
*/ | ||
|
||
pragma solidity 0.4.24; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should test gas differences with a newer version of Solidity too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's only ~100 gas cheaper if we use solidity 0.5.5.
Additionally, I believe all the proxies have to use the same version since they're in the same package, ya? If this is the case and the savings become more substantial it could be worthwhile to split proxies into standalone packages.
@@ -1,5 +1,8 @@ | |||
import { | |||
AssetProxyId, | |||
ERC1155AssetData, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll need to reexport these in the index.ts
of this package and 0x.js (see doc-gen failing tests).
56df883
to
334e935
Compare
9b2197f
to
32b0b0b
Compare
…to be consistent with the ERC1155 reference implementation.
… and there is an overflow.
a33da79
to
22bc1fb
Compare
Description
Asset Proxy for transferring ERC1155 assets. ERC1155 allows a set of fungible / non-fungible assets to exist under the same contract. The proxy uses ERC1155's
safeBatchTransferFrom
to transfer a set of ERC1155 assets between accounts. See #1657 for a minimal ERC1155 implementation.Note - integration tests with the Exchange and MultiAsset Proxy in a separate PR.
Testing instructions
Types of changes
Checklist:
[WIP]
if necessary.