There are two possible scenarios. In both of the scenarios the ultimate moto of the Attacker will be to drain the funds from the Airdrop Vault. Attacker will exploit the vulnerability that is in Soulmate::idToCreationTimestamp function. Furthermore, there is no restriction/validation that msg.sender actually owns any SoulmateToken.
Soulmate token is mintedIn this scenario the attacker can immediately drain all the 500m tokens from the Airdrop Vault.
Attacker will first find out the total balance of Love Tokens held within the Airdrop Vault. Then he will try to replicate the logic of calculating Airdrop::claim::numberOfDaysInCouple variable and he will divide the block.timstamp with the daysInSecond it will result into the number of tokens that can be claimed in one call. Then the attacker will divide the balance / 1e18 with the number of tokens he can claim in one call this is how attacker will compute the total calls (total number of addresses) that he needs.
Now Attacker will call Airdrop::claim function (the above) number of calculated times with different addresses and the attack succceeds. Proof of Concept is also provided in the following section of this report.
In below snippet source line of vulnerability is pointed, in which Airdrop::claim::numberOfDaysInCouple will always be a big number because 0 will be subtracted from block.timestamp because in our scenario Soulmate::idToCreationTimestamp function will always return 0.
Airdrop.sol:
https://github.com/Cyfrin/2024-02-soulmate/blob/b3f9227942ffd5c443ce6bccaa980fea0304c38f/src/Airdrop.sol#L51C5-L89C6
Soulmate tokens are mintedIn this scenario the attacker will drain the remaining tokens from the Airdrop Vault. Attacker will first find out the total balance of Love Tokens remaining in the Airdrop Vault. In this scenario, the higher the number of days passed (since first token was minted) the higher the number of tokens Attacker can claim in a call.
In this scenario Soulmate::idToCreationTimestamp function will always return the creation time of first SoulmateToken id.
The Attacker will again compute the total calls (total number of addresses) that he needs in order to drain all the remaining LoveTokens in Airdrop Vault.
Now Attacker will call Airdrop::claim function (the above) number of calculated times with different addresses and the attack succceeds. For clarity, in the PoC each and every line is commented.
Please note that source of the code is same as provided in Scenario 1.
In this scenario the attacker can immediately drain all the 500m tokens from the Airdrop Vault.
In this scenario the attacker can drain all remaining tokens from the Airdrop Vault.
Manual Review
We should implement multiple mitigations as below:
because there are number of external calls, we should use reentrancy guard
Soulmate::nextID shoule be incremented before updating the state
Airdrop.sol:
Soulmate::nextID increment and validation in Airdrop.solSoulmate.sol:
Airdrop.sol:
High severity, This issue is separated from the flawed `isDivorced()` check presented in issue #168 as even if that is fixed, if ownership is not checked, isDivorced would still default to false and allow bypass to claim airdrops by posing as tokenId 0 in turn resulting in this [important check for token claim is bypassed.](https://github.com/Cyfrin/2024-02-soulmate/blob/b3f9227942ffd5c443ce6bccaa980fea0304c38f/src/Airdrop.sol#L61-L66). #220 is the most comprehensive issue as it correctly recognizes both issues existing within the same function.
High severity, This issue is separated from the flawed `isDivorced()` check presented in issue #168 as even if that is fixed, if ownership is not checked, isDivorced would still default to false and allow bypass to claim airdrops by posing as tokenId 0 in turn resulting in this [important check for token claim is bypassed.](https://github.com/Cyfrin/2024-02-soulmate/blob/b3f9227942ffd5c443ce6bccaa980fea0304c38f/src/Airdrop.sol#L61-L66). #220 is the most comprehensive issue as it correctly recognizes both issues existing within the same function.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.