re-al-Foundation / rwa-contracts

0 stars 0 forks source link

[RWV-03C] Inefficient Batch Migration Mint #86

Closed chasebrownn closed 5 months ago

chasebrownn commented 5 months ago

RWV-03C: Inefficient Batch Migration Mint

Type Severity Location
Gas Optimization RWAVotingEscrow.sol:L270-L271

Description:

The RWAVotingEscrow::migrateBatch function will migrate multiple NFTs, performing a mint operation for each one.

Example:

/**
 * @notice This method is called by the RealReceiver contract to fulfill the cross-chain migration of a batch of 3,3+ NFTs to veRWA NFTs.
 * @param _receiver The account being minted a batch of new tokens.
 * @param _lockedBalances Array of amounts of tokens to lock in new locks.
 * @param _durations Array of durations of new locks (in seconds). Indexes correspond with `_lockedBalances`.
 * @return tokenIds -> Token identifiers minted to `_receiver`.
 */
function migrateBatch(address _receiver, uint256[] memory _lockedBalances, uint256[] memory _durations) external returns (uint256[] memory tokenIds) {
    // get storage
    VotingEscrowStorage storage $ = _getVotingEscrowStorage();
    // msg.sender must be endpoint receiver
    if (msg.sender != $.endpointReceiver) revert NotAuthorized(msg.sender);

    uint256 len = _lockedBalances.length;
    tokenIds = new uint256[](len);

    for (uint256 i; i < len;) {

        // create lock
        tokenIds[i] = _createLock(_receiver, uint208(_lockedBalances[i]), _durations[i]);

        // mints tokens to this contract
        (bool success,) = address($.lockedToken).call(abi.encodeWithSignature("mint(uint256)", _lockedBalances[i]));
        require(success, "mint unsuccessful");

        emit MigrationFulfilled(_receiver, tokenIds[i]);

        unchecked {
            ++i;
        }
    }
}

Recommendation:

We advise the cumulative minted value to be summed within the function's for loop and to be minted once at the end, greatly optimizing the code's gas cost.

chasebrownn commented 5 months ago

Acknowledged