-
Notifications
You must be signed in to change notification settings - Fork 2
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
The last position/s from a given pool can be permanently prevented from being closed, by repaying an arbitrary position more than once #25
Comments
piske-alex (sponsor) confirmed |
alcueca marked the issue as satisfactory |
alcueca marked the issue as selected for report |
This issue is invalid. When the program is deployed in production it will use the Run it again with Here are the docs, please re-check. |
@Arabadzhiew you are right, my bad. But doesn't that mean that #30 and other similar issues that assume a successful underflow/overflow that won't panic are not valid? As it will behave like you described here |
@DadeKuma Given that However, I am not sure how the rest of the issues should be judged, as they still reference the same root cause, although their described impacts are wrong. I'll leave that up to @alcueca to decide. |
As @Arabadzhiew said, when overflow-checks is set to true, panic will be the behaviour. However, here are reasons why I reported the other issue #30
CC: @alcueca |
@koolexcrypto So we shouldn't take the protocol configuration into account during contests? That doesn't make much sense to me, but well, if the rules say so, then so be it.
There are also calls to |
I think this contradicts what you are saying in #15. But if this is true, that means #15 is valid no matter the version of SPL used, as we can assume that they can use a version without safety checks (and also in that case the sponsor added some safety checks in one part of the code, but others were missing) |
To be consistent, I'm going to state that cargo.toml is out of scope, and that the program will underflow without reverting. A recommendation for future Solana/Rust contests is to include configuration files in the scope, and be clear about the release configuration. |
alcueca changed the severity to QA (Quality Assurance) |
alcueca marked the issue as grade-a |
alcueca marked the issue as not selected for report |
Lines of code
https://github.com/code-423n4/2024-04-lavarage/blob/9e8295b542fb71b2ba9b4693e25619585266d19e/libs/smart-contracts/programs/lavarage/src/processor/swapback.rs#L197
Vulnerability details
Impact
The last positions from a given pool will become permanently non-closable, preventing borrowers from claiming back their collateral and repaying their loans, leading to financial losses for them (since all positions are over-collateralized by default)
Proof of Concept
The current implementation of the
repay_sol
function allows it to be called an infinite number of times for positions that have already been closed. However, if we take a look at the following snippet from the function:We can see that the
total_borrowed
value of the node wallet of the trading pool of the position is being decreased byborrowed_amount
on each call to it. What this means is that in the event where the function was to be called more than once for any position, no matter how big or small it is, it will lead to the function always reverting for the last position/s of the given trading pool, as the subtraction fromtotal_borrowed
will always revert due to an arithmetic underflow. This can easily be abused by opening dust-amount positions and then callingrepay_sol
multiple times for them.The following coded PoC demonstrates the issue at question. To run it, paste it after the
Should set maxBorrow
test in thelavarage
describe block in thelavarage.spec.ts
test file and then runanchor test
inlibs/smart-contracts
. The tests insidelavarage.spec.ts
are stateful, so the order in which they are executed does matter.Tools Used
Manual review
Recommended Mitigation Steps
Use
checked_sub
for subtracting theborrowed_amount
from thetotal_borrowed
value, and default to 0 in the case of an underflow:Assessed type
Under/Overflow
The text was updated successfully, but these errors were encountered: