Skip to content

Commit 8cd4bbe

Browse files
Revert "Revert "Merge pull request ProjectOpenSea#505 from ProjectOpenSea/token-transferrer-comment-pass""
This reverts commit 3f0fd92.
1 parent af6b543 commit 8cd4bbe

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

contracts/lib/TokenTransferrer.sol

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ import {
1010

1111
import { ConduitBatch1155Transfer } from "../conduit/lib/ConduitStructs.sol";
1212

13+
/**
14+
* @title TokenTransferrer
15+
* @author 0age
16+
* @custom:coauthor d1ll0n
17+
* @custom:coauthor transmissions11
18+
* @notice TokenTransferrer is a library for performing optimized ERC20, ERC721,
19+
* ERC1155, and batch ERC1155 transfers, used by both Seaport as well as
20+
* by conduits deployed by the ConduitController. Use great caution when
21+
* considering these functions for use in other codebases, as there are
22+
* significant side effects and edge cases that need to be thoroughly
23+
* understood and carefully addressed.
24+
*/
1325
contract TokenTransferrer is TokenTransferrerErrors {
1426
/**
1527
* @dev Internal function to transfer ERC20 tokens from a given originator
@@ -40,6 +52,11 @@ contract TokenTransferrer is TokenTransferrerErrors {
4052
mstore(ERC20_transferFrom_amount_ptr, amount)
4153

4254
// Make call & copy up to 32 bytes of return data to scratch space.
55+
// Scratch space does not need to be cleared ahead of time, as the
56+
// subsequent check will ensure that either at least a full word of
57+
// return data is received (in which case it will be overwritten) or
58+
// that no data is received (in which case scratch space will be
59+
// ignored) on a successful call to the given token.
4360
let callStatus := call(
4461
gas(),
4562
token,
@@ -62,8 +79,8 @@ contract TokenTransferrer is TokenTransferrerErrors {
6279
callStatus
6380
)
6481

65-
// If the transfer failed or it returned nothing:
66-
// Group these because they should be uncommon.
82+
// Handle cases where either the transfer failed or no data was
83+
// returned. Group these, as most transfers will succeed with data.
6784
// Equivalent to `or(iszero(success), iszero(returndatasize()))`
6885
// but after it's inverted for JUMPI this expression is cheaper.
6986
if iszero(and(success, iszero(iszero(returndatasize())))) {
@@ -190,14 +207,14 @@ contract TokenTransferrer is TokenTransferrerErrors {
190207
)
191208
}
192209

193-
// Otherwise revert with error about token not having code:
210+
// Otherwise, revert with error about token not having code:
194211
mstore(NoContract_error_sig_ptr, NoContract_error_signature)
195212
mstore(NoContract_error_token_ptr, token)
196213
revert(NoContract_error_sig_ptr, NoContract_error_length)
197214
}
198215

199-
// Otherwise the token just returned nothing but otherwise
200-
// succeeded; no need to optimize for this as it's not
216+
// Otherwise, the token just returned no data despite the call
217+
// having succeeded; no need to optimize for this as it's not
201218
// technically ERC20 compliant.
202219
}
203220

@@ -747,6 +764,8 @@ contract TokenTransferrer is TokenTransferrerErrors {
747764

748765
// Reset the free memory pointer to the default value; memory must
749766
// be assumed to be dirtied and not reused from this point forward.
767+
// Also note that the zero slot is not reset to zero, meaning empty
768+
// arrays cannot be safely created or utilized until it is restored.
750769
mstore(FreeMemoryPointerSlot, DefaultFreeMemoryPointer)
751770
}
752771
}

0 commit comments

Comments
 (0)