MEDIUM severity: The Forta Staking system, which utilizes the ERC1155 standard for token representation, is vulnerabl. The Forta Staking system, which utilizes the ERC1155 standard for token representation, is vulnerable to reentrancy attacks. Specifically, the `_doSafeTransferAcceptanceCheck()` function, used in the `ERC1155SupplyUpgradeable` contract, allows for reentrancy attacks during mint operations. This vuln...

Vulnerable code:
```\ncontract FortaStaking is \n    BaseComponentUpgradeable, \n    ERC1155SupplyUpgradeable, \n    SubjectTypeValidator, \n    ISlashingExecutor, \n    IStakeMigrator {\n```\n```\nfunction deposit(\n    uint8 subjectType,\n    uint256 subject,\n    uint256 stakeValue\n) external \n    onlyValidSubjectType(subjectType) \n    notAgencyType(subjectType, SubjectStakeAgency.MANAGED)\n    returns (uint256) {\n    if (address(subjectGateway) == address(0)) \n        revert ZeroAddress("subjectGateway");\n    if (!subjectGateway.isStakeActivatedFor(subjectType, subject)) \n        revert StakeInactiveOrSubjectNotFound();\n    address staker = _msgSender();\n    uint256 activeSharesId = FortaStakingUtils.subjectToActive(subjectType, subject);\n    bool reachedMax;\n    (stakeValue, reachedMax) = _getInboundStake(subjectType, subject, stakeValue);\n    if (reachedMax) {\n        emit MaxStakeReached(subjectType, subject);\n    }\n    uint256 sharesValue = stakeToActiveShares(activeSharesId, stakeValue);\n    SafeERC20.safeTransferFrom(stakedToken, staker, address(this), stakeValue);\n\n    _activeStake.mint(activeSharesId, stakeValue);\n    _mint(staker, activeSharesId, sharesValue, new bytes(0));\n    emit StakeDeposited(subjectType, subject, staker, stakeValue);\n    _allocator.depositAllocation(activeSharesId, subjectType, subject, staker, stakeValue, sharesValue);\n    return sharesValue;\n}\n```\n```\nfunction migrate(\n    uint8 oldSubjectType,\n    uint256 oldSubject,\n    uint8 newSubjectType,\n    uint256 newSubject,\n    address staker\n) external onlyRole(SCANNER_2_NODE_RUNNER_MIGRATOR_ROLE) {\n    if (oldSubjectType!= SCANNER_SUBJECT) {\n        revert InvalidSubjectType(oldSubjectType);\n    }\n    if (newSubjectType!= NODE_RUNNER_SUBJECT) {\n        revert InvalidSubjectType(newSubjectType);\n    }\n    if (isFrozen(oldSubjectType, oldSubject)) {\n        revert FrozenSubject();\n    }\n\n    uint256 oldSharesId = FortaStakingUtils.subjectToActive(oldSubjectType, oldSubject);\n    uint256 oldShares = balanceOf(staker, oldSharesId);\n    uint256 stake = activeSharesToStake(oldSharesId, oldShares);\n    uint256 newSharesId = FortaStakingUtils.subjectToActive(newSubjectType, newSubject);\n    uint256 newShares = stakeToActiveShares(newSharesId, stake);\n\n    _activeStake.burn(oldSharesId, stake);\n    _activeStake.mint(newSharesId, stake);\n    _burn(staker, oldSharesId, oldShares);\n    _mint(staker, newSharesId, newShares, bytes(0));\n    emit StakeDeposited(newSubjectType, newSubject, staker, stake);\n    _allocator.depositAllocation(newSharesId, newSubjectType, newSubject, staker, stake, newShares);\n}\n```\n```\nfunction initiateWithdrawal(\n    uint8 subjectType,\n    uint256 subject,\n    uint256 sharesValue\n) external onlyValidSubjectType(subjectType) returns (uint64) {\n    address staker = _msgSender();\n    uint256 activeSharesId = FortaStakingUtils.subjectToActive(subjectType, subject);\n    if (balanceOf(staker, activeSharesId) == 0) {\n        revert NoActiveShares();\n    }\n    uint64 deadline = SafeCast.toUint64(block.timestamp) + _withdrawalDelay;\n\n    _lockingDelay[activeSharesId][staker].setDeadline(deadline);\n\n    uint256 activeShares = Math.min(sharesValue, balanceOf(staker, activeSharesId));\n    uint256 stakeValue = activeSharesToStake(activeSharesId, activeShares);\n    uint256 inactiveShares = stakeToInactiveShares(FortaStakingUtils.activeToInactive(activeSharesId), stakeValue);\n    SubjectStakeAgency agency = getSubjectTypeAgency(subjectType);\n    _activeStake.burn(activeSharesId, stakeValue);\n    _inactiveStake.mint(FortaStakingUtils.activeToInactive(activeSharesId), stakeValue);\n    _burn(staker, activeSharesId, activeShares);\n    _mint(staker, FortaStakingUtils.activeToInactive(activeSharesId), inactiveShares, new bytes(0));\n    if (agency == SubjectStakeAgency.DELEGATED || agency == SubjectStakeAgency.DELEGATOR) {\n        _allocator.withdrawAllocation(activeSharesId, subjectType, subject, staker, stakeValue, activeShares);\n    }\n}\n```