Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: low
Valid

`createEstateNFT` does not link `_asset` to individual NFTs, leading to incorrect pricing

Summary

IMPACT : HIGH
Likelihood : medium

The createEstateNFT function allows the contract owner to set the price of an NFT in a specific asset. However, the _asset is stored in a single contract-wide variable assetToPay rather than being uniquely linked to each NFT. As a result, if the owner later creates another NFT with a different _asset, the price of all previously minted NFTs will be expressed in the newly assigned asset, causing incorrect valuations.

function createEstateNFT(
string memory _description,
uint256 _value,
address _asset
) external onlyOwner {
uint256 nftID = nft.createEstate(_description);
nftValue[nftID] = _value;
--> assetToPay = _asset;
}

Impact

The pricing of previously minted NFTs retroactively changes when a new NFT is minted with a different payment asset. This can lead to significant valuation discrepancies, such as a house initially priced in Bitcoin being mistakenly re-evaluated in USDT, or vice versa, causing severe inconsistencies in asset representation and potential financial losses. Additionally, if an NFT was originally priced in a low-value asset but later gets reassigned to a high-value asset (e.g., switching from USDT to Bitcoin), the cost to buy it out may become unaffordable, effectively trapping the NFT in the contract forever.

Recommendation

add a mapping to connect each NFT to an asset

mapping(uint245 => address) public s_assetToPay;

update createEstateNFT

function createEstateNFT(
string memory _description,
uint256 _value,
address _asset
) external onlyOwner {
uint256 nftID = nft.createEstate(_description);
nftValue[nftID] = _value;
- assetToPay = _asset;
+ assetToPay[nftID] = _asset;
}

update buyOutEstateNFT

function buyOutEstateNFT(
uint256 _nftID
) external onlyBeneficiaryWithIsInherited {
uint256 value = nftValue[_nftID];
uint256 divisor = beneficiaries.length;
uint256 multiplier = beneficiaries.length - 1;
uint256 finalAmount = (value / divisor) * multiplier;
- IERC20(assetToPay).safeTransferFrom(
+ IERC20(assetToPay[_nftId]).safeTransferFrom(
msg.sender,
address(this),
finalAmount
);
+ IERC20(assetToPay[_nftId]).safeTransferFrom(
for (uint256 i = 0; i < beneficiaries.length; i++) {
if (msg.sender == beneficiaries[i]) {
return;
} else {
- IERC20(assetToPay).safeTransfer(
+ IERC20(assetToPay[_nftId]).safeTransfer(
beneficiaries[i],
finalAmount / divisor
);
}
}
nft.burnEstate(_nftID);
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

global asset in NFT values

Support

FAQs

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

Give us feedback!