Skip to content

Commit

Permalink
✨ _initiateTransferFromNFT (#125)
Browse files Browse the repository at this point in the history
Co-authored-by: DNisch <daniel.nisch.dev@gmail.com>
  • Loading branch information
Vectorized and DNisch authored Apr 5, 2024
1 parent 21f0359 commit ab5fa58
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 49 deletions.
99 changes: 50 additions & 49 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -72,76 +72,77 @@ DN404CustomUnitTest:testInitializeCorrectUnitSuccess() (gas: 129962)
DN404CustomUnitTest:testInitializeWithUnitTooLargeReverts() (gas: 33824)
DN404CustomUnitTest:testInitializeWithZeroUnitReverts() (gas: 13897)
DN404CustomUnitTest:testMint() (gas: 162923)
DN404CustomUnitTest:testMintWithoutNFTs(uint256,uint256,uint256) (runs: 258, μ: 154944, ~: 163018)
DN404CustomUnitTest:testMintWithoutNFTs(uint256,uint256,uint256) (runs: 258, μ: 154560, ~: 163018)
DN404CustomUnitTest:testNFTMint() (gas: 57526664)
DN404CustomUnitTest:testNFTMintAndBurn(uint256,uint256,uint256) (runs: 258, μ: 206548, ~: 161918)
DN404CustomUnitTest:testNFTMintViaTransfer(uint256,uint256,uint256) (runs: 258, μ: 218693, ~: 241612)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256) (runs: 258, μ: 635, ~: 692)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256,uint256) (runs: 258, μ: 779, ~: 746)
DN404CustomUnitTest:testNFTMintAndBurn(uint256,uint256,uint256) (runs: 258, μ: 205216, ~: 161918)
DN404CustomUnitTest:testNFTMintViaTransfer(uint256,uint256,uint256) (runs: 258, μ: 216356, ~: 241612)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256) (runs: 258, μ: 638, ~: 692)
DN404CustomUnitTest:testTotalSupplyOverflowsTrick(uint256,uint256,uint256) (runs: 258, μ: 780, ~: 746)
DN404CustomUnitTest:testUnitInvalidCheckTrick(uint256) (runs: 258, μ: 548, ~: 550)
DN404CustomUnitTest:test__codesize() (gas: 28201)
DN404CustomUnitTest:test__codesize() (gas: 28403)
DN404MirrorTest:testBaseERC20() (gas: 114578)
DN404MirrorTest:testFnSelectorNotRecognized() (gas: 7032)
DN404MirrorTest:testFnSelectorNotRecognized() (gas: 7054)
DN404MirrorTest:testLinkMirrorContract() (gas: 45864)
DN404MirrorTest:testLogDirectTransfers() (gas: 378691)
DN404MirrorTest:testLogDirectTransfers() (gas: 378669)
DN404MirrorTest:testLogTransfer() (gas: 120655)
DN404MirrorTest:testNameAndSymbol(string,string) (runs: 258, μ: 207574, ~: 208087)
DN404MirrorTest:testNameAndSymbol(string,string) (runs: 258, μ: 207619, ~: 208132)
DN404MirrorTest:testNotLinked() (gas: 12767)
DN404MirrorTest:testPullOwner() (gas: 112613)
DN404MirrorTest:testPullOwnerWithOwnable() (gas: 3248596)
DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 258, μ: 465848, ~: 465839)
DN404MirrorTest:testPullOwnerWithOwnable() (gas: 3289068)
DN404MirrorTest:testSafeTransferFrom(uint32) (runs: 258, μ: 465845, ~: 465839)
DN404MirrorTest:testSetAndGetApprovalForAll() (gas: 325298)
DN404MirrorTest:testSetAndGetApproved() (gas: 322497)
DN404MirrorTest:testSetAndGetApproved() (gas: 322563)
DN404MirrorTest:testSupportsInterface() (gas: 7544)
DN404MirrorTest:testTokenURI(string,uint256) (runs: 258, μ: 158056, ~: 135791)
DN404MirrorTest:testTransferFrom(uint32) (runs: 258, μ: 366878, ~: 366870)
DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 657212, ~: 616815)
DN404MirrorTest:test__codesize() (gas: 56917)
DN404MirrorTest:testTokenURI(string,uint256) (runs: 258, μ: 158123, ~: 135858)
DN404MirrorTest:testTransferFrom(uint32) (runs: 258, μ: 366833, ~: 366826)
DN404MirrorTest:testTransferFromMixed(uint256) (runs: 258, μ: 664101, ~: 599437)
DN404MirrorTest:test__codesize() (gas: 57305)
DN404OnlyERC20Test:testApprove() (gas: 35803)
DN404OnlyERC20Test:testApprove(address,uint256) (runs: 258, μ: 30505, ~: 31354)
DN404OnlyERC20Test:testBurn() (gas: 51486)
DN404OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 52484, ~: 52687)
DN404OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 45646, ~: 45780)
DN404OnlyERC20Test:testBurn(address,uint256,uint256) (runs: 258, μ: 52397, ~: 52687)
DN404OnlyERC20Test:testBurnInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 45653, ~: 45780)
DN404OnlyERC20Test:testInfiniteApproveTransferFrom() (gas: 104368)
DN404OnlyERC20Test:testMaxSupplyTrick(uint256) (runs: 258, μ: 541, ~: 541)
DN404OnlyERC20Test:testMetadata() (gas: 10044)
DN404OnlyERC20Test:testMint() (gas: 47556)
DN404OnlyERC20Test:testMintOverMaxLimitReverts() (gas: 43535)
DN404OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 47999, ~: 47978)
DN404OnlyERC20Test:testMintz(address,uint256) (runs: 258, μ: 47922, ~: 47978)
DN404OnlyERC20Test:testTransfer() (gas: 77086)
DN404OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 77584, ~: 77543)
DN404OnlyERC20Test:testTransfer(address,uint256) (runs: 258, μ: 77498, ~: 77543)
DN404OnlyERC20Test:testTransferFrom() (gas: 86826)
DN404OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 108050, ~: 109795)
DN404OnlyERC20Test:testTransferFrom(address,address,address,uint256,uint256) (runs: 258, μ: 107891, ~: 109795)
DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts() (gas: 70261)
DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 70540, ~: 71362)
DN404OnlyERC20Test:testTransferFromInsufficientAllowanceReverts(address,uint256,uint256) (runs: 258, μ: 70448, ~: 71362)
DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts() (gas: 76697)
DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 77778, ~: 77818)
DN404OnlyERC20Test:testTransferFromInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 77869, ~: 77818)
DN404OnlyERC20Test:testTransferInsufficientBalanceReverts() (gas: 68196)
DN404OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 69152, ~: 69283)
DN404OnlyERC20Test:testTransferInsufficientBalanceReverts(address,uint256,uint256) (runs: 258, μ: 69238, ~: 69283)
DN404OnlyERC20Test:test__codesize() (gas: 30290)
DN404Test:testBatchNFTLog() (gas: 291443)
DN404Test:testBurnOnTransfer(uint32,address) (runs: 258, μ: 269767, ~: 269767)
DN404Test:testFnSelectorNotRecognized() (gas: 6974)
DN404Test:testInitialize(uint32,address) (runs: 258, μ: 112476, ~: 116293)
DN404Test:testMintAndBurn() (gas: 328527)
DN404Test:testMintAndBurn2() (gas: 275124)
DN404Test:testMintNext() (gas: 627811)
DN404Test:testMintNextMixed(uint256) (runs: 258, μ: 642243, ~: 558410)
DN404Test:testMintOnTransfer(uint32,address) (runs: 258, μ: 287407, ~: 287417)
DN404Test:testMixed(uint256) (runs: 258, μ: 812401, ~: 646502)
DN404Test:testBurnOnTransfer(uint32,address) (runs: 258, μ: 269823, ~: 269823)
DN404Test:testFnSelectorNotRecognized() (gas: 6996)
DN404Test:testInitialize(uint32,address) (runs: 258, μ: 112767, ~: 116271)
DN404Test:testMintAndBurn() (gas: 328471)
DN404Test:testMintAndBurn2() (gas: 275156)
DN404Test:testMintNext() (gas: 627787)
DN404Test:testMintNextMixed(uint256) (runs: 258, μ: 636571, ~: 558426)
DN404Test:testMintOnTransfer(uint32,address) (runs: 258, μ: 287429, ~: 287429)
DN404Test:testMixed(uint256) (runs: 258, μ: 833902, ~: 630141)
DN404Test:testNameAndSymbol(string,string) (runs: 258, μ: 207292, ~: 207805)
DN404Test:testNumAliasesOverflowReverts() (gas: 57345)
DN404Test:testNumAliasesOverflowReverts() (gas: 57310)
DN404Test:testOwnedIds() (gas: 350398)
DN404Test:testOwnedIds(uint256) (runs: 258, μ: 272722, ~: 282630)
DN404Test:testPermit2() (gas: 437378)
DN404Test:testRegisterAndResolveAlias(address,address) (runs: 258, μ: 126496, ~: 126593)
DN404Test:testSetAndGetAux(address,uint88) (runs: 258, μ: 22006, ~: 22344)
DN404Test:testOwnedIds(uint256) (runs: 258, μ: 273238, ~: 281130)
DN404Test:testPermit2() (gas: 437997)
DN404Test:testRegisterAndResolveAlias(address,address) (runs: 258, μ: 126452, ~: 126549)
DN404Test:testSetAndGetAux(address,uint88) (runs: 258, μ: 21988, ~: 22360)
DN404Test:testSetAndGetOperatorApprovals(address,address,bool) (runs: 258, μ: 130828, ~: 140316)
DN404Test:testSetAndGetSkipNFT() (gas: 719127)
DN404Test:testTokenURI(string,uint256) (runs: 258, μ: 157922, ~: 135657)
DN404Test:testTransfersAndBurns() (gas: 461532)
DN404Test:testWrapAround(uint32,uint256) (runs: 258, μ: 347412, ~: 343378)
DN404Test:test__codesize() (gas: 55886)
DN404Test:testSetAndGetSkipNFT() (gas: 716729)
DN404Test:testTokenURI(string,uint256) (runs: 258, μ: 158011, ~: 135746)
DN404Test:testTransferWithMirrorEvent() (gas: 396680)
DN404Test:testTransfersAndBurns() (gas: 461487)
DN404Test:testWrapAround(uint32,uint256) (runs: 258, μ: 348228, ~: 343378)
DN404Test:test__codesize() (gas: 57075)
MappingsTest:testAddressPairMapSetAndGet(address[2],address[2],uint256,uint256) (runs: 258, μ: 45433, ~: 47053)
MappingsTest:testBitmapSetAndGet(uint256) (runs: 258, μ: 463246, ~: 422073)
MappingsTest:testBitmapSetAndGet(uint256,uint256,bool,bool) (runs: 258, μ: 25664, ~: 26361)
Expand All @@ -154,12 +155,12 @@ MappingsTest:testUint32MapSetAndGet(uint256) (runs: 258, μ: 1375364, ~: 1571823
MappingsTest:testUint32MapSetAndGet(uint256,uint256,uint32,uint32) (runs: 258, μ: 42568, ~: 46244)
MappingsTest:testWrapNFTIdWithOverflowCheck(uint256,uint256,uint256) (runs: 258, μ: 827, ~: 852)
MappingsTest:test__codesize() (gas: 7995)
MintTests:test_WhenAmountIsGreaterThan_MAX_SUPPLYOrMintMakesNFTTotalSupplyExceed_MAX_SUPPLY(uint256) (runs: 258, μ: 64532, ~: 64713)
MintTests:test_WhenRecipientAddressHasSkipNFTEnabled(uint256) (runs: 258, μ: 85930, ~: 85920)
MintTests:test_WhenRecipientIsAddress0(uint256) (runs: 258, μ: 31104, ~: 31169)
MintTests:test_WhenRecipientsBalanceDifferenceIsNotUpTo1e18(uint256) (runs: 258, μ: 82890, ~: 82974)
MintTests:test_WhenRecipientsBalanceDifferenceIsUpTo1e18OrAbove(uint256) (runs: 258, μ: 89464, ~: 89492)
MintTests:test__codesize() (gas: 26539)
MintTests:test_WhenAmountIsGreaterThan_MAX_SUPPLYOrMintMakesNFTTotalSupplyExceed_MAX_SUPPLY(uint256) (runs: 258, μ: 64536, ~: 64684)
MintTests:test_WhenRecipientAddressHasSkipNFTEnabled(uint256) (runs: 258, μ: 85845, ~: 85832)
MintTests:test_WhenRecipientIsAddress0(uint256) (runs: 258, μ: 31084, ~: 31147)
MintTests:test_WhenRecipientsBalanceDifferenceIsNotUpTo1e18(uint256) (runs: 258, μ: 82844, ~: 82909)
MintTests:test_WhenRecipientsBalanceDifferenceIsUpTo1e18OrAbove(uint256) (runs: 258, μ: 89352, ~: 89426)
MintTests:test__codesize() (gas: 26725)
NFTMintDN404Test:testAllowlistMint() (gas: 257449)
NFTMintDN404Test:testMint() (gas: 231750)
NFTMintDN404Test:testTotalSupplyReached() (gas: 629566900)
Expand Down
23 changes: 23 additions & 0 deletions src/DN404.sol
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,29 @@ abstract contract DN404 {
}
}

/// @dev Transfers token `id` from `from` to `to`.
/// Also emits an ERC721 {Transfer} event on the `mirrorERC721`.
///
/// Requirements:
///
/// - Call must originate from the mirror contract.
/// - Token `id` must exist.
/// - `from` must be the owner of the token.
/// - `to` cannot be the zero address.
/// `msgSender` must be the owner of the token, or be approved to manage the token.
///
/// Emits a {Transfer} event.
function _initiateTransferFromNFT(address from, address to, uint256 id, address msgSender)
internal
virtual
{
_transferFromNFT(from, to, id, msgSender);
// Emit ERC721 {Transfer} event.
_DNDirectLogs memory directLogs = _directLogsMalloc(1, from, to);
_directLogsAppend(directLogs, id);
_directLogsSend(directLogs, _getDN404Storage().mirrorERC721);
}

/// @dev Transfers token `id` from `from` to `to`.
///
/// Requirements:
Expand Down
26 changes: 26 additions & 0 deletions test/DN404.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ import {DN404Mirror} from "../src/DN404Mirror.sol";
import {LibClone} from "solady/utils/LibClone.sol";
import {LibSort} from "solady/utils/LibSort.sol";

library DN404MirrorTransferEmitter {
event Transfer(address indexed from, address indexed to, uint256 indexed id);

function emitTransfer(address from, address to, uint256 id) internal {
emit Transfer(from, to, id);
}
}

contract DN404Test is SoladyTest {
uint256 private constant _WAD = 1000000000000000000;

Expand Down Expand Up @@ -264,6 +272,24 @@ contract DN404Test is SoladyTest {
assertEq(mirror.ownerAt(1), alice);
}

function testTransferWithMirrorEvent() public {
address initialSupplyOwner = address(1111);
address alice = address(111);
address bob = address(222);

dn.initializeDN404(10 * _WAD, initialSupplyOwner, address(mirror));

vm.prank(initialSupplyOwner);
dn.transfer(alice, 10 * _WAD);

vm.expectEmit(true, true, true, true, address(mirror));
DN404MirrorTransferEmitter.emitTransfer(alice, bob, 3);
vm.prank(alice);
dn.initiateTransferFromNFT(alice, bob, 3);

assertEq(mirror.ownerAt(3), bob);
}

function testMixed(uint256) public {
dn.setUseExistsLookup(_random() % 2 == 0);

Expand Down
4 changes: 4 additions & 0 deletions test/utils/mocks/MockDN404.sol
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ contract MockDN404 is DN404 {
DN404._transferFromNFT(_brutalized(from), _brutalized(to), id, _brutalized(msgSender));
}

function initiateTransferFromNFT(address from, address to, uint256 id) external {
_initiateTransferFromNFT(from, to, id, msg.sender);
}

function _brutalized(address a) internal pure returns (address result) {
/// @solidity memory-safe-assembly
assembly {
Expand Down

0 comments on commit ab5fa58

Please sign in to comment.