Intentional secret reuse can block borrower and lender from accepting liquidation payment
For Dave (the liquidator) to claim the collateral he's purchasing, he must reveal secret D. Once that secret is revealed, Alice and Bob (the borrower and lender) can claim the payment.\\nSecrets must be provided via the `Sales.provideSecret()` function:\\n```\\n function provideSecret(bytes32 sale, bytes32 secret\\_) external {\\n  require(sales[sale].set);\\n  if      (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashA) { secretHashes[sale].secretA = secret\\_; }\\n        else if (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashB) { secretHashes[sale].secretB = secret\\_; }\\n        else if (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashC) { secretHashes[sale].secretC = secret\\_; }\\n        else if (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashD) { secretHashes[sale].secretD = secret\\_; }\\n        else                                                                          { revert(); }\\n }\\n```\\n\\nNote that if Dave chooses the same secret hash as either Alice, Bob, or Charlie (arbiter), there is no way to set `secretHashes[sale].secretD` because one of the earlier conditionals will execute.\\nFor Alice and Bob to later receive payment, they must be able to provide Dave's secret:\\n```\\n function accept(bytes32 sale) external {\\n        require(!accepted(sale));\\n        require(!off(sale));\\n  require(hasSecrets(sale));\\n  require(sha256(abi.encodePacked(secretHashes[sale].secretD)) == secretHashes[sale].secretHashD);\\n```\\n\\nDave can exploit this to obtain the collateral for free:\\nDave looks at Alice's secret hashes to see which will be used in the sale.\\nDave begins the liquidation process, using the same secret hash.\\nAlice and Bob reveal their secrets A and B through the process of moving the collateral.\\nDave now knows the preimage for the secret hash he provided. It was revealed by Alice already.\\nDave uses that secret to obtain the collateral.\\nAlice and Bob now want to receive payment, but they're unable to provide Dave's secret to the `Sales` smart contract due to the order of conditionals in `provideSecret()`.\\nAfter an expiration, Dave can claim a refund.\\nMitigating factors\\nAlice and Bob could notice that Dave chose a duplicate secret hash and refuse to proceed with the sale. This is not something they are likely to do.
Either change the way `provideSecret()` works to allow for duplicate secret hashes or reject duplicate hashes in `create()`.
```\\n function provideSecret(bytes32 sale, bytes32 secret\\_) external {\\n  require(sales[sale].set);\\n  if      (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashA) { secretHashes[sale].secretA = secret\\_; }\\n        else if (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashB) { secretHashes[sale].secretB = secret\\_; }\\n        else if (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashC) { secretHashes[sale].secretC = secret\\_; }\\n        else if (sha256(abi.encodePacked(secret\\_)) == secretHashes[sale].secretHashD) { secretHashes[sale].secretD = secret\\_; }\\n        else                                                                          { revert(); }\\n }\\n```\\n