stake.link

stake.link
DeFiHardhatBridge
27,500 USDC
View results
Submission Details
Severity: medium
Invalid

Lock loss when bridging a lock between chains

Summary

If a reSDL lock is bridged to an other chain to a contract that does not implement onERC721Received the lock will be lost forever along with the funds

Vulnerability Details

When bridging a lock there is only a single check for the destination address, that ensures the receiver to be different from the zero address.
However, there is no protection against bridging the lock to a NFT non-receiving contract and, because of that, someone can lose his lock if the address to receive the lock in the destination chain does not implement onERC721Received.
For example, to transfer the lock between addresses in the same chain, there is the safeTransferFrom function that ensures the receiver to be able to handle NFTs in case the receiver is a smart contract.

Proof of Concept

it('PoC it is possible to bridge a lock to a non-receiving contract', async () => {
let nonReceivingContract: NonRecevingNFTContract
nonReceivingContract = (await deploy('NonRecevingNFTContract')) as NonRecevingNFTContract
await sdlToken.transferAndCall(
sdlPool.address,
toEther(1000),
ethers.utils.defaultAbiCoder.encode(['uint256', 'uint64'], [0, 0])
)
assert.equal(await sdlPool.ownerOf(1), accounts[0])
// A user have a secure way to transfer locks that will not allow the user to send the lock to a non-receiving contract
await expect(sdlPool.functions['safeTransferFrom(address,address,uint256)'](
accounts[0],
nonReceivingContract.address,
1
)).to.be.revertedWith('TransferToNonERC721Implementer()')
// On the other hand, a lock can be bridged to a contract that can NOT handle NFTs and, as a result, the lock will be lost forever.
// Because of this the contract will be getting rewards when distributed and all other users will get affected
await sdlPool.handleIncomingRESDL(nonReceivingContract.address, 2, {
amount: toEther(100),
boostAmount: 0,
startTime: 0,
duration: 0,
expiry: 0,
})
assert.equal(await sdlPool.ownerOf(2), nonReceivingContract.address)
})

Impact

Medium

Tools Used

Manual review

Recommendations

When a lock arrives in a chain, check if the receiver can handle NFTs. If the receiver can NOT manage NFTs, the lock should be returned to the sender

Updates

Lead Judging Commences

0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
draiakoo Submitter
over 1 year ago
0kage Lead Judge
over 1 year ago
0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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