Malicious NFT account actors can still withdraw the contracts ERC20 balances after transferring ownership of the NFT to the LiquidInfrastructureERC20 #741
Malicious NFT account actors can still withdraw the contracts ERC20 balances after transferring ownership of the NFT to the LiquidInfrastructureERC20
Proof of Concept
The protocol enforces that contracts must own the nftContract to withdraw the contracts ERC20 balances
this contract must already be the owner of the nftContract
This invariant is also checked in the addManagedNFT():
function addManagedNFT(address nftContract) public onlyOwner {
LiquidInfrastructureNFT nft = LiquidInfrastructureNFT(nftContract);
address nftOwner = nft.ownerOf(nft.AccountId());
@> require(
nftOwner == address(this),
"this contract does not own the new ManagedNFT"
); @note
ManagedNFTs.push(nftContract);
emit AddManagedNFT(nftContract);
}
Notice it doesn't accept through approvals but only ownership. However, in the LiquidInfrastructureNFT.sol contract, the withdrawBalancesTo() function would still execute if the caller doesn't own the NFT but still approved:
function withdrawBalancesTo(
address[] calldata erc20s,
address destination
) public virtual {
require(
@> _isApprovedOrOwner(_msgSender(), AccountId),
"caller is not the owner of the Account token and is not approved either"
);
_withdrawBalancesTo(erc20s, destination);
}
Now, let's consider this scenario
Bob which is a network provider wants to join Alice network, so he transfers his LiquidInfrastructureNFT to Alice
But right before he transfers it, he approves himself
Now bob's network provide nft is part of the network and owned by Alice but bob is still able to withdraw every revenue token balance in the nft contract
Tools Used
Recommended Mitigation Steps
Consider changing withdrawBalancesTo to only allow the owner of the NFT contract to withdraw the contracts ERC20 balances
Lines of code
https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/main/liquid-infrastructure/contracts/LiquidInfrastructureNFT.sol#L158
Vulnerability details
Impact
Malicious NFT account actors can still withdraw the contracts ERC20 balances after transferring ownership of the NFT to the LiquidInfrastructureERC20
Proof of Concept
The protocol enforces that contracts
must own
thenftContract
to withdraw the contracts ERC20 balancesThis invariant is also checked in the
addManagedNFT()
:Notice it doesn't accept through approvals but only ownership. However, in the LiquidInfrastructureNFT.sol contract, the withdrawBalancesTo() function would still execute if the caller doesn't own the NFT but still approved:
Now, let's consider this scenario
Tools Used
Recommended Mitigation Steps
Consider changing
withdrawBalancesTo
to only allow the owner of the NFT contract to withdraw the contracts ERC20 balancesAssessed type
Access Control