Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It shouldn’t be possible to create a vault with Cally’ own token #224

Open
code423n4 opened this issue May 14, 2022 · 3 comments · Fixed by outdoteth/cally#10
Open
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-05-cally/blob/main/contracts/src/Cally.sol#L193
https://github.com/code-423n4/2022-05-cally/blob/main/contracts/src/Cally.sol#L199

Vulnerability details

Impact

Affected code:

Currently it’s possible to create an ERC-721 vault using Cally’ own address as token, and using the freshly minted vault id as tokenIdOrAmount. This results in a new vault whose ownership is passed to Cally contract immediately upon creation.

The vault allows users to perform buyOption and increase the ETH balance of the Cally contract itself, which is still the vault beneficiary. As soon as an user calls exercise, she will receive the vault.tokenIdOrAmount in exchange, which in this case coincides with the vault nft. However this is of no good because the final user may just initiate a withdrawal, which will:

So the vault will be unusable and the ETH deposited by users to buy/exercise options will remain locked in Cally contract

Proof of Concept

  • Current vault id is, let’s say, 11
  • User deploys a vault with Cally’ address as token and 13 as tokenIdOrAmount
  • Since createVault() mints the vault token to the user, and then transfers the underlying address from the user, an user is able to create a vault with something she doesn’t own at the moment of the createVault() function call, because it’s created while the function runs
  • The vault 13 is pretty limited in functionality, because Cally’ smart contract is the owner
  • However, users can still buy options: so Alice and Bob deposit their premiums
  • Whoever exercise the active option, becomes the vault owner now; this is of no good because no one can actually call withdraw() as it will always revert, and no one can recover the ETH deposited by Alice and Bob as they are locked forever

Tools Used

Editor

Recommended Mitigation Steps

Add the following check at the start of createVault():

require(token != address(this), "Cant use Cally as token");
@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels May 14, 2022
code423n4 added a commit that referenced this issue May 14, 2022
@outdoteth outdoteth added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label May 15, 2022
@outdoteth outdoteth added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label May 16, 2022
@outdoteth
Copy link
Collaborator

outdoteth commented May 16, 2022

This is an exploit that requires users to actively make a very precise and niche mistake. should be medium severity in our opinion.

@outdoteth
Copy link
Collaborator

fix for this issue is here: outdoteth/cally#10

@outdoteth outdoteth reopened this May 17, 2022
@outdoteth outdoteth added the resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) label May 17, 2022
@HardlyDifficult
Copy link
Collaborator

Copying in the POC from GimelSec in #244 because it's an interesting attack to consider for this issue as well.

  1. Alice (Attacker) pack 2 transactions into same block:
    • first transaction: calls createVault to vault a NFT which worth 100 ETH, with parameters:
      • dutchAuctionStartingStrikeIndex is set to 0 (which strikeOptions is 1 ETH)
      • a long durationDays, e.g. 255 days
    • then Alice will get a vaultId 1 token, and Alice do another transaction: call buyOption(1) to get a optionId 2 token
  2. Alice re-vault the vaultId 1 token with strike 89 ETH, and get a vaultId 3 token
  3. Bob see that the auction of vaultId 3 token is 89 ETH, but the vaultId 3 token can get the NFT which worth 100 ETH, so Bob pays 89 ETH, calls buyOption(3), and exercise(4) to get the vaultId 1 token. Then, Bob calls initiateWithdraw(1) and waits for the optionId 2 token to expire (which durationDays is set to 255 days in step 1).
  4. Alice monitors that someone bought the vaultId 1 token, then Alice quickly calls exercise(2). Finally, Alice just pays Bob 1 ETH, and gets the NFT back. Alice also gets 89 ETH which is paid by Bob from the vaultId 3 token.

I agree with (2) Medium for this issue. It can be abused, but the impacted parties can clearly see this is an attempt to subvert the system in some way (a vault of a vault with an NFT, instead of a single value with an NFT as expected). That should be a red flag for Bob in the example above.

@HardlyDifficult HardlyDifficult added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels May 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
3 participants