Understanding renft contract code

Recently I come across ReNFT (https://github.com/re-nft/contracts/blob/main/src/ReNFT.sol) source code. In that code two things I can not understand how they are doing. one is syntax and another one is code logic. I googled I can not get relevant documents / article.

function bundleCall(function(CallData memory) _handler, CallData memory _cd)
    private
{
    require(_cd.nfts.length > 0, "ReNFT::no nfts");
    while (_cd.right != _cd.nfts.length) {
        if (
            (_cd.nfts[_cd.left] == _cd.nfts[_cd.right]) &&
            (is1155(_cd.nfts[_cd.right]))
        ) {
            _cd.right++;
        } else {
            _handler(_cd);
            _cd.left = _cd.right;
            _cd.right++;
        }
    }
    _handler(_cd);
}

function lend(
    address[] memory _nfts,
    uint256[] memory _tokenIds,
    uint256[] memory _lendAmounts,
    uint8[] memory _maxRentDurations,
    bytes4[] memory _dailyRentPrices,
    bytes4[] memory _nftPrices,
    IResolver.PaymentToken[] memory _paymentTokens
) external override notPaused {
    bundleCall(
        handleLend,
        createLendCallData(
            _nfts,
            _tokenIds,
            _lendAmounts,
            _maxRentDurations,
            _dailyRentPrices,
            _nftPrices,
            _paymentTokens
        )
    );
}

function handleLend(CallData memory _cd) private {
    for (uint256 i = _cd.left; i < _cd.right; i++) {
        ensureIsLendable(_cd, i);

        LendingRenting storage item =
            lendingRenting[
                keccak256(
                    abi.encodePacked(
                        _cd.nfts[_cd.left],
                        _cd.tokenIds[i],
                        lendingId
                    )
                )
            ];

        ensureIsNull(item.lending);
        ensureIsNull(item.renting);

        bool nftIs721 = is721(_cd.nfts[i]);
        item.lending = Lending({
            lenderAddress: payable(msg.sender),
            lentAmount: nftIs721 ? 1 : uint8(_cd.lentAmounts[i]),
            maxRentDuration: _cd.maxRentDurations[i],
            dailyRentPrice: _cd.dailyRentPrices[i],
            nftPrice: _cd.nftPrices[i],
            paymentToken: _cd.paymentTokens[i]
        });

        emit Lent(
            _cd.nfts[_cd.left],
            _cd.tokenIds[i],
            nftIs721 ? 1 : uint8(_cd.lentAmounts[i]),
            lendingId,
            msg.sender,
            _cd.maxRentDurations[i],
            _cd.dailyRentPrices[i],
            _cd.nftPrices[i],
            nftIs721,
            _cd.paymentTokens[i]
        );

        lendingId++;
    }

    safeTransfer(
        _cd,
        msg.sender,
        address(this),
        sliceArr(_cd.tokenIds, _cd.left, _cd.right, 0),
        sliceArr(_cd.lentAmounts, _cd.left, _cd.right, 0)
    );
}

In the above solidity code, It seems like bundle function receives one function. Can solidity function receive function as argument? If it is true, can you please give document link / article to explore this.

And one more thing I can not understand in this code is the purpose of left and right variable. Can please someone explain this logic. full code is here https://github.com/re-nft/contracts/blob/main/src/ReNFT.sol

Yes. It's documented on solidity's docs. First instance of mention in the docs i could find it at version 0.4.5

1 Like

@helio.rosa Thanks. It helps me.