Omniscia Evergon Labs Audit

TokenWrapperToERC1155WithERC20FractionsDataManager Manual Review Findings

TokenWrapperToERC1155WithERC20FractionsDataManager Manual Review Findings

TWT-01M: Discrepancy of EIP-1400 Integration

Description:

The EIP-1400 asset class is integrated via its EIP-20 interface during wrapping operations and its EIP-1400 specific interface during unwrapping operations.

This permits an EIP-20 asset to be wrapped as an EIP-1400 asset but never withdrawn, causing it to be permanently locked within the contract.

Impact:

An EIP-20 asset can be wrapped as an EIP-1400 asset but will never be unwrapped, effectively locking funds under normal withdrawal flows in such a case.

Example:

contracts/dataManagers/wrappers/TokenWrapperToERC1155WithERC20FractionsDataManager.sol
499function _vaultTransferERC1400(address token, address to, uint256 value, bytes memory data) internal {
500 dataIndex.write(
501 vaultDO,
502 _datapoint,
503 IVaultOperations.vaultExecute.selector,
504 abi.encode(address(vault), token, abi.encodeWithSelector(IERC1400.transferWithData.selector, to, value, data), 0)
505 );
506}

Recommendation:

We advise the same transfer function to be utilized when wrapping and unwrapping assets to prevent situations whereby an asset can execute one action but cannot another.

Alleviation (c6b23c23d8bcd8cce85049ad959cbd711a37126b):

The EIP-1400 related code was updated to invoke the IERC1400::transferFromWithData function variant ensuring consistency with the unwrapping procedure and thus addressing this exhibit.

TWT-02M: Unresolved TODO Comment

Description:

The TokenWrapperToERC1155WithERC20FractionsDataManager::_vaultTransferERC20 function was meant to utilize a safe-transfer like EIP-20 invocation mechanism yet simply invokes the function and does not validate its return.

Impact:

An EIP-20 asset that might yield false on a transfer failure will not be detected by the TokenWrapperToERC1155WithERC20FractionsDataManager::_vaultTransferERC20 function as it will consider the transfer correctly executed.

Example:

contracts/dataManagers/wrappers/TokenWrapperToERC1155WithERC20FractionsDataManager.sol
452//todo: check transfer returns for each type, dataIndex.write returns the result in execute operation
453//todo: this should be a safeTransferFrom
454function _vaultTransferERC20(address token, address to, uint256 value) internal {
455 dataIndex.write(
456 vaultDO,
457 _datapoint,
458 IVaultOperations.vaultExecute.selector,
459 abi.encode(address(vault), token, abi.encodeWithSelector(IERC20.transfer.selector, to, value), 0)
460 );
461}

Recommendation:

We advise the return of the call to be properly bubbled up to the TokenWrapperToERC1155WithERC20FractionsDataManager implementation from its data index and to be processed similarly to how safe transfer EIP-20 libraries evaluate them.

Alleviation (c6b23c23d8bcd8cce85049ad959cbd711a37126b):

The EIP-20 transfer result is now properly validated at the TokenWrapperToERC1155WithERC20FractionsDataManager level, alleviating this exhibit.