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

KupiaSec - The VaultLib.__liquidateUnchecked() function unnecessarily reorders the already correctly ordered values of raReceived and ctReceived from UniswapV2Router #214

Closed
sherlock-admin2 opened this issue Sep 10, 2024 · 57 comments
Labels
Escalation Resolved This issue's escalations have been approved/rejected Non-Reward This issue will not receive a payout Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin2
Copy link
Contributor

sherlock-admin2 commented Sep 10, 2024

KupiaSec

High

The VaultLib.__liquidateUnchecked() function unnecessarily reorders the already correctly ordered values of raReceived and ctReceived from UniswapV2Router

Summary

The __liquidateUnchecked() function removes liquidity and receives the corresponding RA and CT from UniswapV2, returning the amounts of RA and CT received. When removing liquidity, the removeLiquidity() function of the UniswapV2Router returns raReceived and ctReceived, which are the exact amounts of RA and CT corresponding to the removed liquidity, regardless of the order of tokens RA and CT in the Uniswap pool. However, in the __liquidateUnchecked() function, these values are reordered as if they represent the received amounts of token0 and token1, assuming that token0 = CT and token1 = RA.

Vulnerability Detail

As noted in line 282 of the __liquidateUnchecked() function, the ammRouter.removeLiquidity() function returns two values: raReceived and ctReceived. These values represent the exact amounts of RA and CT received from the Uniswap pool, even in the case where token0 = CT and token1 = RA (see UniswapV2Router02.sol). Therefore, there is no need to reorder these values. However, at line 284, the function reorders them, assuming token0 = CT and token1 = RA. As a result, when token0 = CT and token1 = RA, the values of raReceived and ctReceived will be interchanged. This leads to incorrect behavior in the _liquidatedLp() function, which processes expired states when issuing new DS. Consequently, an incorrect RA amount is reserved in the reserve pool, potentially leading to a loss of RA for users.

VaultLib.sol

    function __liquidateUnchecked(
        State storage self,
        address raAddress,
        address ctAddress,
        IUniswapV2Router02 ammRouter,
        IUniswapV2Pair ammPair,
        uint256 lp
    ) internal returns (uint256 raReceived, uint256 ctReceived) {
        ammPair.approve(address(ammRouter), lp);

        // amountAMin & amountBMin = 0 for 100% tolerence
        (raReceived, ctReceived) =
282         ammRouter.removeLiquidity(raAddress, ctAddress, lp, 0, 0, address(this), block.timestamp);

284     (raReceived, ctReceived) = MinimalUniswapV2Library.reverseSortWithAmount224(
            ammPair.token0(), ammPair.token1(), raAddress, ctAddress, raReceived, ctReceived
        );

        self.vault.config.lpBalance -= lp;
    }

----------------------------

UniswapV2Router02.sol

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) {
        address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);
        IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
        (uint amount0, uint amount1) = IUniswapV2Pair(pair).burn(to);
        (address token0,) = UniswapV2Library.sortTokens(tokenA, tokenB);
@>      (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT');
        require(amountB >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT');
    }

Impact

Loss of RA for users.

Code Snippet

https://github.com/sherlock-audit/2024-08-cork-protocol/tree/main/Depeg-swap/contracts/libraries/VaultLib.sol#L270-L289

https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol#L116

Tool used

Manual Review

Recommendation

Eliminate the reordering.

    function __liquidateUnchecked(
        State storage self,
        address raAddress,
        address ctAddress,
        IUniswapV2Router02 ammRouter,
        IUniswapV2Pair ammPair,
        uint256 lp
    ) internal returns (uint256 raReceived, uint256 ctReceived) {
        ammPair.approve(address(ammRouter), lp);

        // amountAMin & amountBMin = 0 for 100% tolerence
        (raReceived, ctReceived) =
            ammRouter.removeLiquidity(raAddress, ctAddress, lp, 0, 0, address(this), block.timestamp);

-       (raReceived, ctReceived) = MinimalUniswapV2Library.reverseSortWithAmount224(
-           ammPair.token0(), ammPair.token1(), raAddress, ctAddress, raReceived, ctReceived
-       );

        self.vault.config.lpBalance -= lp;
    }
@github-actions github-actions bot added the High A High severity issue. label Sep 14, 2024
@ziankork
Copy link
Collaborator

yes this is valid and have been fixed prior to our trading competition. will provide links later

@sherlock-admin3 sherlock-admin3 added Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed labels Sep 24, 2024
@sherlock-admin3 sherlock-admin3 changed the title Acrobatic Cider Cougar - The VaultLib.__liquidateUnchecked() function unnecessarily reorders the already correctly ordered values of raReceived and ctReceived from UniswapV2Router KupiaSec - The VaultLib.__liquidateUnchecked() function unnecessarily reorders the already correctly ordered values of raReceived and ctReceived from UniswapV2Router Sep 25, 2024
@sherlock-admin3 sherlock-admin3 added the Reward A payout will be made for this issue label Sep 25, 2024
@sherlock-admin4
Copy link
Contributor

sherlock-admin4 commented Sep 26, 2024

Escalate,
This is gas optimization issue at best. The reverseSortWithAmount224() function has the following implementation:

    function reverseSortWithAmount224(
        address token0,
        address token1,
        address ra,
        address ct,
        uint256 token0Amount,
        uint256 token1Amount
    ) internal pure returns (uint256 raAmountOut, uint256 ctAmountOut) {
        if (token0 == ra && token1 == ct) {
            raAmountOut = token0Amount;
            ctAmountOut = token1Amount;
        } else if (token0 == ct && token1 == ra) {
            raAmountOut = token1Amount;
            ctAmountOut = token0Amount;
        } else {
            revert InvalidToken();
       

You've deleted an escalation for this issue.

@sherlock-admin4 sherlock-admin4 added the Escalated This issue contains a pending escalation label Sep 26, 2024
@KupiaSecAdmin
Copy link

@AtanasDimulski, I think you misunderstood something.

The issue is simply due to the unnecessary application of the reverseSortWithAmount224() function.

That function reorders the amounts, which were already well-ordered.

@sherlock-admin4 sherlock-admin4 removed the Escalated This issue contains a pending escalation label Sep 27, 2024
@AtanasDimulski
Copy link

@KupiaSecAdmin you are correct, my mistake. Nice catch!

@0xsimao
Copy link
Collaborator

0xsimao commented Sep 27, 2024

escalate

This issue is invalid because it requires the ra address to be bigger than the ct address.
Ra and ct are picked by the admin, in which ct results from the create opcode, so the admin has complete control on them. Place where the admin picks ra. Ct is created here, which uses the create opcode, so the admin can create dummy ra,ct pairs just to get a ct address bigger than ra.
As such, it should pick values that do not cause issues.

(External) Admin trust assumptions: When a function is access restricted, only values for specific function variables mentioned in the README can be taken into account when identifying an attack path.

If no values are provided, the (external) admin is trusted to use values that will not cause any issues.

@sherlock-admin3
Copy link

escalate

This issue is invalid because it requires the ra address to be bigger than the ct address.
Ra and ct are picked by the admin, in which ct results from the create opcode, so the admin has complete control on them. Place where the admin picks ra. Ct is created here, which uses the create opcode, so the admin can create dummy ra,ct pairs just to get a ct address bigger than ra.
As such, it should pick values that do not cause issues.

(External) Admin trust assumptions: When a function is access restricted, only values for specific function variables mentioned in the README can be taken into account when identifying an attack path.

If no values are provided, the (external) admin is trusted to use values that will not cause any issues.

You've created a valid escalation!

To remove the escalation from consideration: Delete your comment.

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

@sherlock-admin4 sherlock-admin4 added the Escalated This issue contains a pending escalation label Sep 27, 2024
@KupiaSecAdmin
Copy link

@0xsimao

I don't agree with your insistence.

  1. ct is not a variable that the admin needs to monitor closely to avoid any issues. If the admin consistently chooses ct to be greater than ra, there is no need to implement mechanisms to sort raAmount and ctAmount.

so the admin can create dummy ra,ct pairs just to get a ct address bigger than ra.

  1. Whenever ct is created, a Uniswap V2 pool (ra, ct) is established, which incurs significant costs. Therefore, creating dummy entries until ct > ra is not a feasible action.

  2. Additionally, when issuing new (ds, ct), there is an expiration time that prevents immediate issuance of new (ds, ct).

@0xsimao
Copy link
Collaborator

0xsimao commented Sep 27, 2024

@KupiaSecAdmin still, the admin picks the ra and ct address, so according to the rule, it is trusted to pick values that do not cause any issues.

@KupiaSecAdmin
Copy link

@0xsimao

I totally disagree with your insistence.

  1. Additionally, when issuing new (ds, ct), there is an expiration time that prevents immediate issuance of new (ds, ct).

When issuing a new (ds, ct), the previous (ds, ct) must be expired. Therefore, once a new (ds, ct) is issued, it cannot be immediately canceled, even if ct < ra. How can the admin pick the ct address?

This is a clear bug, and the sponsor has also confirmed it.

So, I believe the judge will make the correct decision.

@0xsimao
Copy link
Collaborator

0xsimao commented Sep 27, 2024

It does not have to cancel it, it can create dummy ra, ct pairs. ct is created via the create() opcode, so we can always find ct addresses bigger than ra. The address used for the ra in the dummy can be another, just to increase the creation nonce of the contract and change the ct address.

Additionally, the admin can order the issuance of ra, ct pairs according to their addresses. If we have ra1 = 5, ra2 = 3, ct1 = 4, ct2 = 6, the admin can do pairs ra2,ct1 and ra1,ct2. If the ra address is bigger than the next ct, and the admin really wants to use this ra, he can create other pairs to increase the ct address and then create the pair with the correct ct.

Another option for the admin is to create a wrapper for ra that has a smaller address, if needed.

I am not saying the bug does not exist, it does, but it is invalid according to the sherlock rules, as it is picked solely by the admin and the admin is trusted to use values that do not cause issues.

@sherlock-admin2
Copy link
Contributor Author

The protocol team fixed this issue in the following PRs/commits:
Cork-Technology/Depeg-swap@4944b7d

@KupiaSecAdmin
Copy link

(External) Admin trust assumptions: When a function is access restricted, only values for specific function variables mentioned in the README can be taken into account when identifying an attack path.

If no values are provided, the (external) admin is trusted to use values that will not cause any issues.

@0xsimao,

Your assertions do not align with the Sherlock rule you mentioned.

1. The method by which the admin controls CT, as mentioned in your earlier comment, is not intended and appears to be an overestimation of the protocol design to force it to align with the Sherlock rule.

It does not have to cancel it, it can create dummy ra, ct pairs. ct is created via the create() opcode, so we can always find ct addresses bigger than ra. The address used for the ra in the dummy can be another, just to increase the creation nonce of the contract and change the ct address.

Additionally, the admin can order the issuance of ra, ct pairs according to their addresses. If we have ra1 = 5, ra2 = 3, ct1 = 4, ct2 = 6, the admin can do pairs ra2,ct1 and ra1,ct2. If the ra address is bigger than the next ct, and the admin really wants to use this ra, he can create other pairs to increase the ct address and then create the pair with the correct ct.

Another option for the admin is to create a wrapper for ra that has a smaller address, if needed.

I am not saying the bug does not exist, it does, but it is invalid according to the sherlock rules, as it is picked solely by the admin and the admin is trusted to use values that do not cause issues.

Your method does not focus on controlling specific function variables; rather, it centers on managing the create opcode nonce by modifying the protocol design. Therefore, it does not align with the Sherlock rule.

2. The variable values of the issueNewDs() function are determined by the protocol strategy, not to prevent CT < RA.

(External) Admin trust assumptions: When a function is access restricted, only values for specific function variables mentioned in the README can be taken into account when identifying an attack path.

If no values are provided, the (external) admin is trusted to use values that will not cause any issues.

I believe you were pointing to the issueNewDs() function as access restricted. This function has the following parameters:

    function issueNewDs(Id id, uint256 expiry, uint256 exchangeRates, uint256 repurchaseFeePrecentage)

These parameters do not have arbitrary values; each has a specific meaning. Therefore, the admin does not set these values to generate a CT greater than RA. Consequently, the Sherlock rule you mentioned does not apply to my issue.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 1, 2024

The admin is trusted to use the right ra and ct values, and they are fully in their control. There are ra and ct values that the admin can use that do not cause any issues. Hence, the rule applies.

The id in the function points to a specific ra, so it can choose the ra value. The ct value comes from the nonce, as explained earlier, and can also be picked to not cause any issues.

@KupiaSecAdmin
Copy link

The admin is trusted to use the right ra and ct values, and they are fully in their control. There are ra and ct values that the admin can use that do not cause any issues. Hence, the rule applies.

CT is not under the admin's control; it is clearly an internal address that the admin disregards.

The id in the function points to a specific ra, so it can choose the ra value. The ct value comes from the nonce, as explained earlier, and can also be picked to not cause any issues.

Id denotes (ra, pa). Yes, we are concentrating on a specific fixed Id.

For a given Id, your method of controlling the generated CT is not feasible. It could only be possible if the admin creates a fake Id to increase the nonce. This approach does not involve controlling function variables; rather, it stems from an overestimation of the protocol design.

Therefore, the rule does not apply. I believe there may have been a misunderstanding.

Once again, I trust that the judge will make the right decision.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 4, 2024

CT is not under the admin's control; it is clearly an internal address that the admin disregards.
For a given Id, your method of controlling the generated CT is not feasible. It could only be possible if the admin creates a fake Id to increase the nonce. This approach does not involve controlling function variables; rather, it stems from an overestimation of the protocol design.

The admin would disregard it if it was not trusted. But he is trusted, so he should do the correct thing and use proper ra and ct values, which is possible, as mentioned before.

As per the argument that the admin should not create dummy ct addresses to get one higher than ra and prevent this issue, this is the reason #180 was invalidated, as the admin could do this to create another pool. So here the admin must also be able to use a proper ct and mitigate this issue.

@WangSecurity
Copy link

As I understand, regardless of the admin input, the raRecevied and ctReceived would always be correct because they're re-ordered by Uniswap. Then, they're swapped the second time, regardless of the admin input, which leads to an issue. Hence, planning to reject the escalation and leave the issue as it is.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 10, 2024

@WangSecurity if ra is token0 the issue does not happen. As the admin picks these addresses, it is trusted to not cause issues. And the ra and ct addresses are part of the admin input, the Id argument.

@SakshamGuruji3
Copy link

I have to agree with @0xsimao here , since the admin can prevent the issue by picking the correct address it should not be an issue

@KupiaSecAdmin
Copy link

And the ra and ct addresses are part of the admin input, the Id argument.

We are focusing on a specific fixed Id (which denotes (ra, pa)). Therefore, first and foremost, ra is not part of the admin's input. Additionally, ct is also not part of the admin's input; rather, it is an address generated internally without any consideration.

As I mentioned earlier:

  • The issue cannot be resolved simply by changing function variables.

    For a given Id, the function variables expiry, exchangeRates, and repurchaseFeePercentage used to issue new (ds, ct) cannot be arbitrarily chosen to generate ct > ra; each variable has a specific meaning.

        function issueNewDs(Id id, uint256 expiry, uint256 exchangeRates, uint256 repurchaseFeePrecentage)
    
  • The methods you mentioned for generating ct greater than ra do not rely on changing function variables. Instead, they require significant changes to the protocol design. Furthermore, implementing these methods whenever issuing new (ds, ct) values is both costly and impractical.

Therefore, the Sherlock rule does not apply to my issue.

Additionally, the protocol's implementation of mechanisms to sort reserve values in the Uniswap V2 pool at multiple points indicates that the admin does not care ct.

@WangSecurity
Copy link

I would agree about the admin rule if the admin indeed could just specify ra and ct they want to use, but here, for that to happen, the admin would have to do additional manipulations that are not relevant to creating a pair (e.g. create dummy ra, ct pairs). Moreover, regardless of the admin input in removeLiquidity, the ra and ct tokens would be correctly ordered after the first time.

Hence, the decision remains, reject the escalation and leave the issue as it is.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 12, 2024

Moreover, regardless of the admin input in removeLiquidity, the ra and ct tokens would be correctly ordered after the first time.

I do not understand this part, if the admin picks ra and ct correctly the issue does not happen.

@WangSecurity
Copy link

As was said above, the admin doesn't just pick ra and ct, and for them to be ordered without any issues after the second re-order, the admin has to complete manipulations irrelevant to creating a new pair. Regardless of the admin's input, they will still be ordered correctly in removeLiquidity and then unnecessarily swapped.

The decision remains, reject the escalation and leave the issue as it is.

@KupiaSecAdmin
Copy link

It is guaranteed that it will work eventually, and there are other ids, they can send them in different order to make it work. So yes, it is doable and the admin rule applies, as the admin picks ra < ct and there are no issues.

When will it work? If a nonce increment of 100 is required, can the admin afford such a significant gas cost? Even, for every new issuance?

What if a nonce increment of 1000 is necessary? Impractical!

and there are other ids, they can send them in different order to make it work.

No. If all other ids have not yet reached their expiration time, how can the admin issue new cts for them? It is impossible.

I prefer not to continue discussing the uncertain actions you’re proposing, as they lack guarantees and practicality.

Additionally, the Sherlock rule does not state that the admin can use undesigned function variables (your dummy ids) to prevent issues, so it does not apply here.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 15, 2024

No. If all other ids have not yet reached their expiration time, how can the admin issue new cts for them? It is impossible.

They may use dummy cts if the other ids are not enough.

The rule applies because not all ras cause issues. Even ra addresses that cause issues can be fixed by using dummy ct addresses.

And if they deem it impractical they can redeploy without losses. And the admin is trusted to use ra addresses that are practical for them (not being very big in this case). But the issue present in this report will not happen because the admin is trusted to use ra values that do not cause issues.

@KupiaSecAdmin
Copy link

They may use dummy cts if the other ids are not enough.

The rule applies because not all ras cause issues. Even ra addresses that cause issues can be fixed by using dummy ct addresses.

Still it has no guarantee.

And if it becomes impractical they can redeploy without losses. But the issue present in this report will not happen because the admin is trusted to use ra values that do not cause issues.

Redeploy? There’s still no guarantee that a similar situation won’t occur with the new deployment. Additionally, redeploying is not the approach the Sherlock rule recommends for preventing issues.

Let’s not extend your uncertain actions into even more unguaranteed and impractical solutions.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 15, 2024

Redeploy? There’s still no guarantee that a similar situation won’t occur with the new deployment. Additionally, redeploying is not the approach the Sherlock rule recommends for preventing issues.

I do not know what they would do if they redeployed but according to the admin rule the issue described in this report will not happen for sure.

@KupiaSecAdmin
Copy link

but according to the admin rule the issue described in this report will not happen for sure.

There’s no logical context here.

@0xsimao
Copy link
Collaborator

0xsimao commented Oct 15, 2024

The context is that ra < ct does not cause issues

@KupiaSecAdmin
Copy link

Please don’t repeat the same logic which is not perfect.

@WangSecurity
Copy link

Actually, I'll revert to my previous decision to leave the issue as is. The admin indeed supplies the RA address, while CT is not an admin input. Yes, there are some theoretical ways for the admin to manipulate the CT address, but @KupiaSecAdmin very well explained why these ways are impractical and are not how the protocol is designed to work. Moreover, this can happen with fairly any RA address besides very small addresses, which are not even tokens.

Hence, I agree that admin rules here are not applicable because the way to potentially mitigate an issue are impractical and are not expected. Planning to reject the escalation and leave the issue as it is, will apply that decision tomorrow 10 AM UTC.

@Pheonix244001
Copy link

Hi @WangSecurity
As far as I have understood, the reason to validate/invalidate this issue is due to admin intervention.

However, the issue #174 also mentioned a fix where the admin had to donate in the uniV2 pool and call sync in order to mitigate for all DS issuances.

Moreover, the reason of invalidating #114 is also admin intervention , it is not justified that for some issues the admin rule is stretched or loosely applied just because the admin intervention is higher , all such issues where admin can somehow fix the issue should be invalidated or it does not make sense to invalidate some since anyhow admin has to go the extra mile and fix regardless if its tough or easy.

@AtanasDimulski
Copy link

AtanasDimulski commented Oct 16, 2024

There is a fundamental difference between #174 and both #214 and #114. In #174 the problem is introduced by a malicious actor, in #214 and #114 the code doesn't work as expected. However, I agree that #214 and #114 should be either both valid, or both invalid. I strongly belive both of those issues are valid.

@Pheonix244001
Copy link

@AtanasDimulski
It does not matter if the code is working as intended or not , or any fundamental logic.
The discussion is about admin intervention for resolving the issue which is relevant for all.

@AtanasDimulski
Copy link

@Pheonix244001 this is not correct, your issue assumes that pairs will be deployed with 0 liquidity, and you haven't provided any pre conditions as to how this can happen. Then a malicious actor provides only 1 RA in an already deployed pair, and this isn't even a DOS because the next block someone donates 1 CT and the issue is resolved, the attacker can't do anything to continue the DOS. Both #214 and #114 originate from the fact that the code doesn't work as expected without a malicious actor performing any actions to cause the issue. Then the actions that the admin has to execute are way more complicated, those types of actions are impractical and not expected from an admin.

@Pheonix244001
Copy link

@AtanasDimulski please read the original comment , the fact that admin has to intervene and perform actions himself (as mentioned in the report for all new DS issuances ) is sufficient proof itself that all admin interventions leading to fixing the issue should be counted and hence all of the issues should be invalidated or validated , loosening the rules and definitions based on how hard/easy is the action is not justified.

your issue assumes that pairs will be deployed with 0 liquidity

This is not an assumption see issueNewDs() where a new pair is created.

@WangSecurity
Copy link

Firstly, #174 wasn't invalidated based on the admin rules and I don't think I mentioned them there (even if mentioned, the decision wasn't based on them in the end).
Secondly, the main difference between #214 and #114 is the practicality. In this issue, it can take hundreds of pairs to be created to mitigate the issue. In #114, one swap on RA: CT pair (or two swaps) is enough to mitigate the issue. That's the distinct difference between the two and one is deemed valid and the other one is not.

The decision remains the same, reject the escalation and leave the issue as it is. Planning to apply the decision in a couple of hours.

@Pheonix244001
Copy link

Let me reiterate #174 here for one last time here:
initializeModuleCore -> issueNewDs() -> create ra/ct pair -> attacker donates 1 wei of ra -> calls sync() -> ra 1 wei ct 0 -> addLiquidity will revert since ct needs to be non zero.

The same can be applied after expiry when issueNewDs() is called again.

In both the cases, we require admin intervention to manually donate ct to the pair in order for addLiquidity to work again. There can be hundreds of pairs for which issueNewDs() is called.

@SakshamGuruji3
Copy link

@WangSecurity I have to agree on the fact that "how hard" it is for the admin to mitigate the issue should not be a roadblock and decisive if one issue is validated and the other is not , the fact that both issues can be mitigated by admin acctions should be treated equally , admin rules have to be same for all regardless

@AtanasDimulski
Copy link

@AtanasDimulski please read the original comment , the fact that admin has to intervene and perform actions himself (as mentioned in the report for all new DS issuances ) is sufficient proof itself that all admin interventions leading to fixing the issue should be counted and hence all of the issues should be invalidated or validated , loosening the rules and definitions based on how hard/easy is the action is not justified.

your issue assumes that pairs will be deployed with 0 liquidity

This is not an assumption see issueNewDs() where a new pair is created.

I have read the function numerous times as I spend a lot of time defending #114, you are omitting the part that if in the previous pair there is liquidity that liquidity will be provided to the newly created pair, and the whole scenario you described becomes obsolete. The pre-conditions you haven't provided are that the pair has to be created with 0 liquidity and how this can happen.

@AtanasDimulski
Copy link

Firstly, #174 wasn't invalidated based on the admin rules and I don't think I mentioned them there (even if mentioned, the decision wasn't based on them in the end). Secondly, the main difference between #214 and #114 is the practicality. In this issue, it can take hundreds of pairs to be created to mitigate the issue. In #114, one swap on RA: CT pair (or two swaps) is enough to mitigate the issue. That's the distinct difference between the two and one is deemed valid and the other one is not.

The decision remains the same, reject the escalation and leave the issue as it is. Planning to apply the decision in a couple of hours.

@WangSecurity you can't say that because of the fact that in #214 the admin may have to deploy hundreds of pairs, this is not practical. But assume in #114 that the admin has to donate and manipulate the price of the previous uniV2 pair, is practical and completely disregard the fact that the only way he can achieve this in 100% of the cases is if he frontruns other users. Frontruing and saying that if someone else manipulates the price back falls under the 1 block DOS rules is exactly the same thing in this scenario.

@WangSecurity
Copy link

@AtanasDimulski and @SakshamGuruji3 made a good point. I see your side and how it would be unfair to validate one finding but invalidate another one in this case. To keep the fairness and consistency, I will change my decision now again towards invalidating this. Tagging @KupiaSecAdmin for transparency. The decision to accept and invalidate will be applied in a couple of hours.

Note: excuse me for the confusion from my last messages of tossing between A and B

@WangSecurity WangSecurity removed the High A High severity issue. label Oct 16, 2024
@sherlock-admin2 sherlock-admin2 added Non-Reward This issue will not receive a payout and removed Reward A payout will be made for this issue labels Oct 16, 2024
@WangSecurity
Copy link

Result:
Invalid
Unique

@sherlock-admin2 sherlock-admin2 removed the Escalated This issue contains a pending escalation label Oct 16, 2024
@sherlock-admin3 sherlock-admin3 added the Escalation Resolved This issue's escalations have been approved/rejected label Oct 16, 2024
@sherlock-admin4
Copy link
Contributor

Escalations have been resolved successfully!

Escalation status:

@KupiaSecAdmin
Copy link

@WangSecurity,

I have a question about the Sherlock rule.

(External) Admin trust assumptions: When a function is access restricted, only values for specific function variables mentioned in the README can be taken into account when identifying an attack path.

If no values are provided, the (external) admin is trusted to use values that will not cause any issues.

Does this rule imply that the admin can use undesigned function variables (dummy ids) to prevent issues?

I believe the rule indicates that any issues can be invalidated if the admin can prevent them by using and modifying legitimate function variables.

Since dummy ids are not legitimate function variables, I think applying the rule to this issue distorts its intent.

I have always stated, firstly, that the rule does not apply to this issue. Practicality is merely a secondary concern.

@WangSecurity
Copy link

I wouldn’t say this exact rule is applied here. The issue is invalidated, because it’s in the admin’s control to prevent the issue and if they can make calls in a way this issue doesn’t happen, this should be low/invalid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Escalation Resolved This issue's escalations have been approved/rejected Non-Reward This issue will not receive a payout Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

10 participants