The SalvorLending::validateLoanOffer function will validate that the LibLending::Token payload has been signed by the contract's signer and is meant for the msg.sender, however, the NFT for which the token ID is signed for is not validated.
Impact:
It is presently possible for a borrower to spoof the validator into signing a LibOrder::Token payload for NFT collection A and NFT ID X while utilizing it for NFT collection B and the same NFT ID X.
Example:
/**
* @notice Validates a loan offer and corresponding token. This internal function ensures the loan offer and token meet various criteria including active pool, valid token signature, matching salts, sender authenticity, and signature expiry.
* @param _loanOffer The loan offer to validate.
* @param _token The token associated with the loan offer.
* @param _tokenSignature The signature of the token.
*/
function validateLoanOffer(LibLending.LoanOffer memory _loanOffer, LibLending.Token memory _token, bytes memory _tokenSignature) internal {
require(_loanOffer.amount > 0, "lend amount cannot be 0");
require(lendingPools[_loanOffer.nftContractAddress].isActive, "pool is not active");
require(_hashTypedDataV4(LibLending.hashToken(_token)).recover(_tokenSignature) == validator, "token signature is not valid");
require(keccak256(abi.encodePacked(_token.salt)) == keccak256(abi.encodePacked(_loanOffer.salt)), "salt does not match");
require(_token.sender == msg.sender, "token signature does not belong to msg.sender");
require(_token.blockNumber + blockRange > block.number, "token signature has been expired");
bytes32 hash = LibLending.hashKey(_loanOffer);
require(_loanOffer.size > sizes[hash], "size is filled");
sizes[hash] += 1;
}
Recommendation:
We advise the code to ensure that the NFT collection is also validated as a token ID by itself is insufficient in validating an operation on the contract by an external signer.
SLG-06M: Weak Association of Token & Offer
Description:
The
SalvorLending::validateLoanOffer
function will validate that theLibLending::Token
payload has been signed by the contract'ssigner
and is meant for themsg.sender
, however, the NFT for which the token ID is signed for is not validated.Impact:
It is presently possible for a borrower to spoof the
validator
into signing aLibOrder::Token
payload for NFT collection A and NFT ID X while utilizing it for NFT collection B and the same NFT ID X.Example:
Recommendation:
We advise the code to ensure that the NFT collection is also validated as a token ID by itself is insufficient in validating an operation on the contract by an external
signer
.