Professional Documents
Culture Documents
Verichains Draft Audit Report - DGG Smartcontracts - v1.0
Verichains Draft Audit Report - DGG Smartcontracts - v1.0
_collections[_collection][_collectionId].status = CollectionStatus.Close;
_collectionAddressSet.remove(_collection); // ISSUE AT THIS LINE
Recommendation
The code can be fixed as below:
_collections[_collection][_collectionId].status = CollectionStatus.Close;
// _collectionAddressSet.remove(_collection); <-- REMOVE THIS
emit CollectionClose(_collection, _collectionId);
}
Discussion: We have noticed that the code allows for the creation of multiple collections at a single collection
address. However, if each collection address only has a single collection ID, then the aforementioned issue can be
considered a false positive. Nevertheless, we have also identified another issue with the _collections mapping
and identified best practices to address this problem.
Scenario impact:
Owner list a NFT on market that token buy is BNB (allowed) and price is 1 BNB.
Owner edit token buy to ETH.
Front-end display 1 unknown token and user click buy then approve quickly.
NFT was sold with 1 ETH.
Recommendation
The code can be fixed as below:
function modifyAskOrder(
address _collection,
uint256 _tokenId,
uint256 _newPrice,
address _newTokenBuy,
//address _tokenBuy, <-- REMOVE THIS LINE
uint256 _collectionId
) external nonReentrant {
// Verify new price is not too low/high
require(_newPrice >= minimumAskPrice && _newPrice <= maximumAskPrice, "Order: Price
not within range");
Recommendation
The code can be fixed as below:
function buyToken(
address _collection,
uint256 _tokenId,
uint256 _price,
address _tokenBuy, // ADD THIS
uint256 _collectionId
) public nonReentrant {
Ask memory askOrder = _askDetails[_collection][_tokenId];
Recommendation
Calculate carefully before transfer. We suggest have a global mapping to store total pending revenue
( totalPendingRevenue ) for each token. And then, the code can be fixed as below:
IERC20(_token).safeTransfer(address(msg.sender), amountToRecover);
Recommendation
The contract must have a mapping to store all NFT listed on market (ex: tokenListed ) and then the code
can be fixed as below:
Recommendation
require(_collections[_collection][_collectionId].creatorAddress !=
address(0),"Operations: Collection not listed");
require(_collections[_collection][_collectionId].collectionId != 0,"Operations:
Collection not listed");
Example:
1. admin create a collection A => _collectionAddressSet has A and status A in _collections is OPEN
2. admin remove collection A => _collectionAddressSet removed A and status A in _collections is CLOSED
3. admin modify collection A => _collectionAddressSet does not have A and status A in _collections is
OPEN
Recommendation
The code can be fixed like the first issue:
function closeCollectionForTradingAndListing(address _collection,uint256 _collectionId)
external onlyAdmin {
require(_collections[_collection][_collectionId].status == CollectionStatus.Open,
"Operations: Collection not listed"); // FIXED
_collections[_collection][_collectionId].status = CollectionStatus.Close;
// _collectionAddressSet.remove(_collection); <-- REMOVE THIS
emit CollectionClose(_collection, _collectionId);
}
Recommendation
The code can be fixed as below:
function modifyCollection(
address _collection,
address _creator,
address _whitelistChecker,
uint256 _tradingFee,
uint256 _creatorFee,
uint256 _collectionId
) external {
//require(_collectionAddressSet.contains(_collection), "Operations: Collection not
listed");
require(_collections[_collection][_collectionId].creatorAddress !=
address(0),"Operations: Collection not listed");
require(
(_creatorFee == 0 && _creator == address(0)) || (_creatorFee != 0 && _creator
!= address(0)),
"Operations: Creator parameters incorrect"
);
collection = Collection({
status: CollectionStatus.Open,
creatorAddress: _creator,
whitelistChecker: _whitelistChecker,
tradingFee: _tradingFee,
creatorFee: _creatorFee,
collectionId: _collectionId
});
} else {
collection = Collection({
status: CollectionStatus.Open,
creatorAddress: _creator,
whitelistChecker: _whitelistChecker,
tradingFee: collection.tradingFee,
creatorFee: collection.creatorFee,
collectionId: _collectionId
});
}