Pieces Protocol

First Flight #32
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Anyone can mint from deployed ERC20 causing devaluation of the token

Summary

Due to missing restriction on ERC20ToGenerateNftFraccion.sol , anyone can mint from the deployed ERC20 when an NFT is divided causing the ERC20 to not have value and initial owner of the NFT to can't claim the NFT even though if he didn't intend to sell/transfer it's ERC20.

Vulnerability Details

When TokenDivider::divideNftis used, a new ERC20 token is created

function divideNft(
address nftAddress,
uint256 tokenId,
uint256 amount
)
external
onlyNftOwner(nftAddress, tokenId)
onlyNftOwner(nftAddress, tokenId)
{
[...]
ERC20ToGenerateNftFraccion erc20Contract = new ERC20ToGenerateNftFraccion(
string(abi.encodePacked(ERC721(nftAddress).name(), "Fraccion")),
string(abi.encodePacked("F", ERC721(nftAddress).symbol()))
);

This token represents the shares of the Nft.

Though anyone can use the mint function in the newly created ERC20 and then get a share of the NFT as there is no restriction

function mint(address _to, uint256 _amount) public {
_mint(_to, _amount);
}

POC

function testAnyoneCanMintFromDeployedERC20(
address randomUser,
uint256 amount
) public nftDivided {
vm.assume(randomUser != USER && randomUser != address(0));
vm.assume(amount <= type(uint256).max - AMOUNT);
ERC20ToGenerateNftFraccion fraccionERC20 = ERC20ToGenerateNftFraccion(
tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address
);
assertEq(
tokenDivider.getErc20TotalMintedAmount(address(fraccionERC20)),
AMOUNT
);
vm.prank(randomUser);
fraccionERC20.mint(randomUser, amount);
assertEq(fraccionERC20.balanceOf(randomUser), amount);
}

Impact

  • The user calling TokenDivider::divideNft can instantly loose the ability to claim back its Nft even though he didn't intend to transfer or sell it's ERC20 shares

  • Anyone can sell ERC20 shares even without buying any share

Recommendations

Inherit from openzeppelin Ownable and restrict the mint with onlyOwnermodifier

-contract ERC20ToGenerateNftFraccion is ERC20, ERC20Burnable {
+contract ERC20ToGenerateNftFraccion is ERC20, ERC20Burnable, Ownable {
constructor(
string memory _name,
string memory _symbol
- ) ERC20(_name, _symbol) {}
+ ) ERC20(_name, _symbol) Ownable{msg.sender}
- function mint(address _to, uint256 _amount) public {
+ function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
}
}
Updates

Lead Judging Commences

juan_pedro_ventu Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Lack of token access control chekcs

Any person can mint the ERC20 token generated in representation of the NFT

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.